rename godis/redis/reply to godis/redis/protocol

This commit is contained in:
hdt3213
2022-04-10 08:35:51 +08:00
parent c97f3aae6e
commit 37ef7d8a34
55 changed files with 774 additions and 774 deletions

View File

@@ -7,7 +7,7 @@ import (
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/parser" "github.com/hdt3213/godis/redis/parser"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"io" "io"
"os" "os"
"strconv" "strconv"
@@ -78,7 +78,7 @@ func (handler *Handler) handleAof() {
handler.pausingAof.RLock() // prevent other goroutines from pausing aof handler.pausingAof.RLock() // prevent other goroutines from pausing aof
if p.dbIndex != handler.currentDB { if p.dbIndex != handler.currentDB {
// select db // select db
data := reply.MakeMultiBulkReply(utils.ToCmdLine("SELECT", strconv.Itoa(p.dbIndex))).ToBytes() data := protocol.MakeMultiBulkReply(utils.ToCmdLine("SELECT", strconv.Itoa(p.dbIndex))).ToBytes()
_, err := handler.aofFile.Write(data) _, err := handler.aofFile.Write(data)
if err != nil { if err != nil {
logger.Warn(err) logger.Warn(err)
@@ -86,7 +86,7 @@ func (handler *Handler) handleAof() {
} }
handler.currentDB = p.dbIndex handler.currentDB = p.dbIndex
} }
data := reply.MakeMultiBulkReply(p.cmdLine).ToBytes() data := protocol.MakeMultiBulkReply(p.cmdLine).ToBytes()
_, err := handler.aofFile.Write(data) _, err := handler.aofFile.Write(data)
if err != nil { if err != nil {
logger.Warn(err) logger.Warn(err)
@@ -135,13 +135,13 @@ func (handler *Handler) LoadAof(maxBytes int) {
logger.Error("empty payload") logger.Error("empty payload")
continue continue
} }
r, ok := p.Data.(*reply.MultiBulkReply) r, ok := p.Data.(*protocol.MultiBulkReply)
if !ok { if !ok {
logger.Error("require multi bulk reply") logger.Error("require multi bulk protocol")
continue continue
} }
ret := handler.db.Exec(fakeConn, r.Args) ret := handler.db.Exec(fakeConn, r.Args)
if reply.IsErrorReply(ret) { if protocol.IsErrorReply(ret) {
logger.Error("exec err", err) logger.Error("exec err", err)
} }
} }

View File

@@ -6,17 +6,17 @@ import (
"github.com/hdt3213/godis/datastruct/set" "github.com/hdt3213/godis/datastruct/set"
SortedSet "github.com/hdt3213/godis/datastruct/sortedset" SortedSet "github.com/hdt3213/godis/datastruct/sortedset"
"github.com/hdt3213/godis/interface/database" "github.com/hdt3213/godis/interface/database"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
"time" "time"
) )
// EntityToCmd serialize data entity to redis command // EntityToCmd serialize data entity to redis command
func EntityToCmd(key string, entity *database.DataEntity) *reply.MultiBulkReply { func EntityToCmd(key string, entity *database.DataEntity) *protocol.MultiBulkReply {
if entity == nil { if entity == nil {
return nil return nil
} }
var cmd *reply.MultiBulkReply var cmd *protocol.MultiBulkReply
switch val := entity.Data.(type) { switch val := entity.Data.(type) {
case []byte: case []byte:
cmd = stringToCmd(key, val) cmd = stringToCmd(key, val)
@@ -34,17 +34,17 @@ func EntityToCmd(key string, entity *database.DataEntity) *reply.MultiBulkReply
var setCmd = []byte("SET") var setCmd = []byte("SET")
func stringToCmd(key string, bytes []byte) *reply.MultiBulkReply { func stringToCmd(key string, bytes []byte) *protocol.MultiBulkReply {
args := make([][]byte, 3) args := make([][]byte, 3)
args[0] = setCmd args[0] = setCmd
args[1] = []byte(key) args[1] = []byte(key)
args[2] = bytes args[2] = bytes
return reply.MakeMultiBulkReply(args) return protocol.MakeMultiBulkReply(args)
} }
var rPushAllCmd = []byte("RPUSH") var rPushAllCmd = []byte("RPUSH")
func listToCmd(key string, list *List.LinkedList) *reply.MultiBulkReply { func listToCmd(key string, list *List.LinkedList) *protocol.MultiBulkReply {
args := make([][]byte, 2+list.Len()) args := make([][]byte, 2+list.Len())
args[0] = rPushAllCmd args[0] = rPushAllCmd
args[1] = []byte(key) args[1] = []byte(key)
@@ -53,12 +53,12 @@ func listToCmd(key string, list *List.LinkedList) *reply.MultiBulkReply {
args[2+i] = bytes args[2+i] = bytes
return true return true
}) })
return reply.MakeMultiBulkReply(args) return protocol.MakeMultiBulkReply(args)
} }
var sAddCmd = []byte("SADD") var sAddCmd = []byte("SADD")
func setToCmd(key string, set *set.Set) *reply.MultiBulkReply { func setToCmd(key string, set *set.Set) *protocol.MultiBulkReply {
args := make([][]byte, 2+set.Len()) args := make([][]byte, 2+set.Len())
args[0] = sAddCmd args[0] = sAddCmd
args[1] = []byte(key) args[1] = []byte(key)
@@ -68,12 +68,12 @@ func setToCmd(key string, set *set.Set) *reply.MultiBulkReply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(args) return protocol.MakeMultiBulkReply(args)
} }
var hMSetCmd = []byte("HMSET") var hMSetCmd = []byte("HMSET")
func hashToCmd(key string, hash dict.Dict) *reply.MultiBulkReply { func hashToCmd(key string, hash dict.Dict) *protocol.MultiBulkReply {
args := make([][]byte, 2+hash.Len()*2) args := make([][]byte, 2+hash.Len()*2)
args[0] = hMSetCmd args[0] = hMSetCmd
args[1] = []byte(key) args[1] = []byte(key)
@@ -85,12 +85,12 @@ func hashToCmd(key string, hash dict.Dict) *reply.MultiBulkReply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(args) return protocol.MakeMultiBulkReply(args)
} }
var zAddCmd = []byte("ZADD") var zAddCmd = []byte("ZADD")
func zSetToCmd(key string, zset *SortedSet.SortedSet) *reply.MultiBulkReply { func zSetToCmd(key string, zset *SortedSet.SortedSet) *protocol.MultiBulkReply {
args := make([][]byte, 2+zset.Len()*2) args := make([][]byte, 2+zset.Len()*2)
args[0] = zAddCmd args[0] = zAddCmd
args[1] = []byte(key) args[1] = []byte(key)
@@ -102,16 +102,16 @@ func zSetToCmd(key string, zset *SortedSet.SortedSet) *reply.MultiBulkReply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(args) return protocol.MakeMultiBulkReply(args)
} }
var pExpireAtBytes = []byte("PEXPIREAT") var pExpireAtBytes = []byte("PEXPIREAT")
// MakeExpireCmd generates command line to set expiration for the given key // MakeExpireCmd generates command line to set expiration for the given key
func MakeExpireCmd(key string, expireAt time.Time) *reply.MultiBulkReply { func MakeExpireCmd(key string, expireAt time.Time) *protocol.MultiBulkReply {
args := make([][]byte, 3) args := make([][]byte, 3)
args[0] = pExpireAtBytes args[0] = pExpireAtBytes
args[1] = []byte(key) args[1] = []byte(key)
args[2] = []byte(strconv.FormatInt(expireAt.UnixNano()/1e6, 10)) args[2] = []byte(strconv.FormatInt(expireAt.UnixNano()/1e6, 10))
return reply.MakeMultiBulkReply(args) return protocol.MakeMultiBulkReply(args)
} }

View File

@@ -5,7 +5,7 @@ import (
"github.com/hdt3213/godis/interface/database" "github.com/hdt3213/godis/interface/database"
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
@@ -55,7 +55,7 @@ func (handler *Handler) DoRewrite(ctx *RewriteCtx) error {
// rewrite aof tmpFile // rewrite aof tmpFile
for i := 0; i < config.Properties.Databases; i++ { for i := 0; i < config.Properties.Databases; i++ {
// select db // select db
data := reply.MakeMultiBulkReply(utils.ToCmdLine("SELECT", strconv.Itoa(i))).ToBytes() data := protocol.MakeMultiBulkReply(utils.ToCmdLine("SELECT", strconv.Itoa(i))).ToBytes()
_, err := tmpFile.Write(data) _, err := tmpFile.Write(data)
if err != nil { if err != nil {
return err return err
@@ -128,7 +128,7 @@ func (handler *Handler) FinishRewrite(ctx *RewriteCtx) {
} }
// sync tmpFile's db index with online aofFile // sync tmpFile's db index with online aofFile
data := reply.MakeMultiBulkReply(utils.ToCmdLine("SELECT", strconv.Itoa(ctx.dbIdx))).ToBytes() data := protocol.MakeMultiBulkReply(utils.ToCmdLine("SELECT", strconv.Itoa(ctx.dbIdx))).ToBytes()
_, err = tmpFile.Write(data) _, err = tmpFile.Write(data)
if err != nil { if err != nil {
logger.Error("tmp file rewrite failed: " + err.Error()) logger.Error("tmp file rewrite failed: " + err.Error())
@@ -153,7 +153,7 @@ func (handler *Handler) FinishRewrite(ctx *RewriteCtx) {
handler.aofFile = aofFile handler.aofFile = aofFile
// reset selected db 重新写入一次 select 指令保证 aof 中的数据库与 handler.currentDB 一致 // reset selected db 重新写入一次 select 指令保证 aof 中的数据库与 handler.currentDB 一致
data = reply.MakeMultiBulkReply(utils.ToCmdLine("SELECT", strconv.Itoa(handler.currentDB))).ToBytes() data = protocol.MakeMultiBulkReply(utils.ToCmdLine("SELECT", strconv.Itoa(handler.currentDB))).ToBytes()
_, err = handler.aofFile.Write(data) _, err = handler.aofFile.Write(data)
if err != nil { if err != nil {
panic(err) panic(err)

View File

@@ -12,7 +12,7 @@ import (
"github.com/hdt3213/godis/lib/consistenthash" "github.com/hdt3213/godis/lib/consistenthash"
"github.com/hdt3213/godis/lib/idgenerator" "github.com/hdt3213/godis/lib/idgenerator"
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/jolestar/go-commons-pool/v2" "github.com/jolestar/go-commons-pool/v2"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
@@ -97,7 +97,7 @@ func (cluster *Cluster) Exec(c redis.Connection, cmdLine [][]byte) (result redis
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
logger.Warn(fmt.Sprintf("error occurs: %v\n%s", err, string(debug.Stack()))) logger.Warn(fmt.Sprintf("error occurs: %v\n%s", err, string(debug.Stack())))
result = &reply.UnknownErrReply{} result = &protocol.UnknownErrReply{}
} }
}() }()
cmdName := strings.ToLower(string(cmdLine[0])) cmdName := strings.ToLower(string(cmdLine[0]))
@@ -105,27 +105,27 @@ func (cluster *Cluster) Exec(c redis.Connection, cmdLine [][]byte) (result redis
return database2.Auth(c, cmdLine[1:]) return database2.Auth(c, cmdLine[1:])
} }
if !isAuthenticated(c) { if !isAuthenticated(c) {
return reply.MakeErrReply("NOAUTH Authentication required") return protocol.MakeErrReply("NOAUTH Authentication required")
} }
if cmdName == "multi" { if cmdName == "multi" {
if len(cmdLine) != 1 { if len(cmdLine) != 1 {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
return database2.StartMulti(c) return database2.StartMulti(c)
} else if cmdName == "discard" { } else if cmdName == "discard" {
if len(cmdLine) != 1 { if len(cmdLine) != 1 {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
return database2.DiscardMulti(c) return database2.DiscardMulti(c)
} else if cmdName == "exec" { } else if cmdName == "exec" {
if len(cmdLine) != 1 { if len(cmdLine) != 1 {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
return execMulti(cluster, c, nil) return execMulti(cluster, c, nil)
} else if cmdName == "select" { } else if cmdName == "select" {
if len(cmdLine) != 2 { if len(cmdLine) != 2 {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
return execSelect(c, cmdLine) return execSelect(c, cmdLine)
} }
@@ -134,7 +134,7 @@ func (cluster *Cluster) Exec(c redis.Connection, cmdLine [][]byte) (result redis
} }
cmdFunc, ok := router[cmdName] cmdFunc, ok := router[cmdName]
if !ok { if !ok {
return reply.MakeErrReply("ERR unknown command '" + cmdName + "', or not supported in cluster mode") return protocol.MakeErrReply("ERR unknown command '" + cmdName + "', or not supported in cluster mode")
} }
result = cmdFunc(cluster, c, cmdLine) result = cmdFunc(cluster, c, cmdLine)
return return
@@ -178,11 +178,11 @@ func (cluster *Cluster) groupBy(keys []string) map[string][]string {
func execSelect(c redis.Connection, args [][]byte) redis.Reply { func execSelect(c redis.Connection, args [][]byte) redis.Reply {
dbIndex, err := strconv.Atoi(string(args[1])) dbIndex, err := strconv.Atoi(string(args[1]))
if err != nil { if err != nil {
return reply.MakeErrReply("ERR invalid DB index") return protocol.MakeErrReply("ERR invalid DB index")
} }
if dbIndex >= config.Properties.Databases { if dbIndex >= config.Properties.Databases {
return reply.MakeErrReply("ERR DB index is out of range") return protocol.MakeErrReply("ERR DB index is out of range")
} }
c.SelectDB(dbIndex) c.SelectDB(dbIndex)
return reply.MakeOkReply() return protocol.MakeOkReply()
} }

View File

@@ -6,7 +6,7 @@ import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/client" "github.com/hdt3213/godis/redis/client"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
) )
@@ -44,7 +44,7 @@ func (cluster *Cluster) relay(peer string, c redis.Connection, args [][]byte) re
} }
peerClient, err := cluster.getPeerClient(peer) peerClient, err := cluster.getPeerClient(peer)
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
defer func() { defer func() {
_ = cluster.returnPeerClient(peer, peerClient) _ = cluster.returnPeerClient(peer, peerClient)

View File

@@ -4,7 +4,7 @@ import (
"github.com/hdt3213/godis/config" "github.com/hdt3213/godis/config"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )

View File

@@ -2,7 +2,7 @@ package cluster
import ( import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
) )
@@ -10,7 +10,7 @@ import (
// if the given writeKeys are distributed on different node, Del will use try-commit-catch to remove them // if the given writeKeys are distributed on different node, Del will use try-commit-catch to remove them
func Del(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply { func Del(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
if len(args) < 2 { if len(args) < 2 {
return reply.MakeErrReply("ERR wrong number of arguments for 'del' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'del' command")
} }
keys := make([]string, len(args)-1) keys := make([]string, len(args)-1)
for i := 1; i < len(args); i++ { for i := 1; i < len(args); i++ {
@@ -36,7 +36,7 @@ func Del(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
} else { } else {
resp = cluster.relay(peer, c, makeArgs("Prepare", peerArgs...)) resp = cluster.relay(peer, c, makeArgs("Prepare", peerArgs...))
} }
if reply.IsErrorReply(resp) { if protocol.IsErrorReply(resp) {
errReply = resp errReply = resp
rollback = true rollback = true
break break
@@ -56,10 +56,10 @@ func Del(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
if !rollback { if !rollback {
var deleted int64 = 0 var deleted int64 = 0
for _, resp := range respList { for _, resp := range respList {
intResp := resp.(*reply.IntReply) intResp := resp.(*protocol.IntReply)
deleted += intResp.Code deleted += intResp.Code
} }
return reply.MakeIntReply(int64(deleted)) return protocol.MakeIntReply(int64(deleted))
} }
return errReply return errReply
} }

View File

@@ -2,7 +2,7 @@ package cluster
import ( import (
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )

View File

@@ -2,23 +2,23 @@ package cluster
import ( import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
) )
// FlushDB removes all data in current database // FlushDB removes all data in current database
func FlushDB(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply { func FlushDB(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
replies := cluster.broadcast(c, args) replies := cluster.broadcast(c, args)
var errReply reply.ErrorReply var errReply protocol.ErrorReply
for _, v := range replies { for _, v := range replies {
if reply.IsErrorReply(v) { if protocol.IsErrorReply(v) {
errReply = v.(reply.ErrorReply) errReply = v.(protocol.ErrorReply)
break break
} }
} }
if errReply == nil { if errReply == nil {
return &reply.OkReply{} return &protocol.OkReply{}
} }
return reply.MakeErrReply("error occurs: " + errReply.Error()) return protocol.MakeErrReply("error occurs: " + errReply.Error())
} }
// FlushAll removes all data in cluster // FlushAll removes all data in cluster

View File

@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
) )
@@ -13,7 +13,7 @@ const keyExistsErr = "key exists"
// MGet atomically get multi key-value from cluster, writeKeys can be distributed on any node // MGet atomically get multi key-value from cluster, writeKeys can be distributed on any node
func MGet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply { func MGet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
if len(cmdLine) < 2 { if len(cmdLine) < 2 {
return reply.MakeErrReply("ERR wrong number of arguments for 'mget' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'mget' command")
} }
keys := make([]string, len(cmdLine)-1) keys := make([]string, len(cmdLine)-1)
for i := 1; i < len(cmdLine); i++ { for i := 1; i < len(cmdLine); i++ {
@@ -24,11 +24,11 @@ func MGet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
groupMap := cluster.groupBy(keys) groupMap := cluster.groupBy(keys)
for peer, group := range groupMap { for peer, group := range groupMap {
resp := cluster.relay(peer, c, makeArgs("MGET", group...)) resp := cluster.relay(peer, c, makeArgs("MGET", group...))
if reply.IsErrorReply(resp) { if protocol.IsErrorReply(resp) {
errReply := resp.(reply.ErrorReply) errReply := resp.(protocol.ErrorReply)
return reply.MakeErrReply(fmt.Sprintf("ERR during get %s occurs: %v", group[0], errReply.Error())) return protocol.MakeErrReply(fmt.Sprintf("ERR during get %s occurs: %v", group[0], errReply.Error()))
} }
arrReply, _ := resp.(*reply.MultiBulkReply) arrReply, _ := resp.(*protocol.MultiBulkReply)
for i, v := range arrReply.Args { for i, v := range arrReply.Args {
key := group[i] key := group[i]
resultMap[key] = v resultMap[key] = v
@@ -38,14 +38,14 @@ func MGet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
for i, k := range keys { for i, k := range keys {
result[i] = resultMap[k] result[i] = resultMap[k]
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
// MSet atomically sets multi key-value in cluster, writeKeys can be distributed on any node // MSet atomically sets multi key-value in cluster, writeKeys can be distributed on any node
func MSet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply { func MSet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
argCount := len(cmdLine) - 1 argCount := len(cmdLine) - 1
if argCount%2 != 0 || argCount < 1 { if argCount%2 != 0 || argCount < 1 {
return reply.MakeErrReply("ERR wrong number of arguments for 'mset' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'mset' command")
} }
size := argCount / 2 size := argCount / 2
@@ -79,7 +79,7 @@ func MSet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
} else { } else {
resp = cluster.relay(peer, c, makeArgs("Prepare", peerArgs...)) resp = cluster.relay(peer, c, makeArgs("Prepare", peerArgs...))
} }
if reply.IsErrorReply(resp) { if protocol.IsErrorReply(resp) {
errReply = resp errReply = resp
rollback = true rollback = true
break break
@@ -93,7 +93,7 @@ func MSet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
rollback = errReply != nil rollback = errReply != nil
} }
if !rollback { if !rollback {
return &reply.OkReply{} return &protocol.OkReply{}
} }
return errReply return errReply
@@ -103,7 +103,7 @@ func MSet(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
func MSetNX(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply { func MSetNX(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
argCount := len(cmdLine) - 1 argCount := len(cmdLine) - 1
if argCount%2 != 0 || argCount < 1 { if argCount%2 != 0 || argCount < 1 {
return reply.MakeErrReply("ERR wrong number of arguments for 'msetnx' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'msetnx' command")
} }
size := argCount / 2 size := argCount / 2
@@ -139,10 +139,10 @@ func MSetNX(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
} else { } else {
resp = cluster.relay(peer, c, makeArgs("Prepare", peerArgs...)) resp = cluster.relay(peer, c, makeArgs("Prepare", peerArgs...))
} }
if reply.IsErrorReply(resp) { if protocol.IsErrorReply(resp) {
re := resp.(reply.ErrorReply) re := resp.(protocol.ErrorReply)
if re.Error() == keyExistsErr { if re.Error() == keyExistsErr {
errReply = reply.MakeIntReply(0) errReply = protocol.MakeIntReply(0)
} else { } else {
errReply = resp errReply = resp
} }
@@ -158,7 +158,7 @@ func MSetNX(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
_, errReply = requestCommit(cluster, c, txID, groupMap) _, errReply = requestCommit(cluster, c, txID, groupMap)
rollback = errReply != nil rollback = errReply != nil
if !rollback { if !rollback {
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
return errReply return errReply
} }
@@ -166,7 +166,7 @@ func MSetNX(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
func prepareMSetNx(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) redis.Reply { func prepareMSetNx(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) redis.Reply {
args := cmdLine[1:] args := cmdLine[1:]
if len(args)%2 != 0 { if len(args)%2 != 0 {
return reply.MakeSyntaxErrReply() return protocol.MakeSyntaxErrReply()
} }
size := len(args) / 2 size := len(args) / 2
values := make([][]byte, size) values := make([][]byte, size)
@@ -176,14 +176,14 @@ func prepareMSetNx(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) red
values[i] = args[2*i+1] values[i] = args[2*i+1]
} }
re := cluster.db.ExecWithLock(conn, utils.ToCmdLine2("ExistIn", keys...)) re := cluster.db.ExecWithLock(conn, utils.ToCmdLine2("ExistIn", keys...))
if reply.IsErrorReply(re) { if protocol.IsErrorReply(re) {
return re return re
} }
_, ok := re.(*reply.EmptyMultiBulkReply) _, ok := re.(*protocol.EmptyMultiBulkReply)
if !ok { if !ok {
return reply.MakeErrReply(keyExistsErr) return protocol.MakeErrReply(keyExistsErr)
} }
return reply.MakeOkReply() return protocol.MakeOkReply()
} }
func init() { func init() {

View File

@@ -2,7 +2,7 @@ package cluster
import ( import (
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )

View File

@@ -4,7 +4,7 @@ import (
"github.com/hdt3213/godis/database" "github.com/hdt3213/godis/database"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
) )
@@ -16,7 +16,7 @@ var relayMultiBytes = []byte(relayMulti)
// cmdLine == []string{"exec"} // cmdLine == []string{"exec"}
func execMulti(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) redis.Reply { func execMulti(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) redis.Reply {
if !conn.InMultiState() { if !conn.InMultiState() {
return reply.MakeErrReply("ERR EXEC without MULTI") return protocol.MakeErrReply("ERR EXEC without MULTI")
} }
defer conn.SetMultiState(false) defer conn.SetMultiState(false)
cmdLines := conn.GetQueuedCmdLine() cmdLines := conn.GetQueuedCmdLine()
@@ -40,7 +40,7 @@ func execMulti(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) redis.R
} }
groupMap := cluster.groupBy(keys) groupMap := cluster.groupBy(keys)
if len(groupMap) > 1 { if len(groupMap) > 1 {
return reply.MakeErrReply("ERR MULTI commands transaction must within one slot in cluster mode") return protocol.MakeErrReply("ERR MULTI commands transaction must within one slot in cluster mode")
} }
var peer string var peer string
// assert len(groupMap) == 1 // assert len(groupMap) == 1
@@ -48,7 +48,7 @@ func execMulti(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) redis.R
peer = p peer = p
} }
// out parser not support reply.MultiRawReply, so we have to encode it // out parser not support protocol.MultiRawReply, so we have to encode it
if peer == cluster.self { if peer == cluster.self {
return cluster.db.ExecMulti(conn, watching, cmdLines) return cluster.db.ExecMulti(conn, watching, cmdLines)
} }
@@ -78,40 +78,40 @@ func execMultiOnOtherNode(cluster *Cluster, conn redis.Connection, peer string,
} else { } else {
rawRelayResult = cluster.relay(peer, conn, relayCmdLine) rawRelayResult = cluster.relay(peer, conn, relayCmdLine)
} }
if reply.IsErrorReply(rawRelayResult) { if protocol.IsErrorReply(rawRelayResult) {
return rawRelayResult return rawRelayResult
} }
_, ok := rawRelayResult.(*reply.EmptyMultiBulkReply) _, ok := rawRelayResult.(*protocol.EmptyMultiBulkReply)
if ok { if ok {
return rawRelayResult return rawRelayResult
} }
relayResult, ok := rawRelayResult.(*reply.MultiBulkReply) relayResult, ok := rawRelayResult.(*protocol.MultiBulkReply)
if !ok { if !ok {
return reply.MakeErrReply("execute failed") return protocol.MakeErrReply("execute failed")
} }
rep, err := parseEncodedMultiRawReply(relayResult.Args) rep, err := parseEncodedMultiRawReply(relayResult.Args)
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
return rep return rep
} }
// execRelayedMulti execute relayed multi commands transaction // execRelayedMulti execute relayed multi commands transaction
// cmdLine format: _multi watch-cmdLine base64ed-cmdLine // cmdLine format: _multi watch-cmdLine base64ed-cmdLine
// result format: base64ed-reply list // result format: base64ed-protocol list
func execRelayedMulti(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) redis.Reply { func execRelayedMulti(cluster *Cluster, conn redis.Connection, cmdLine CmdLine) redis.Reply {
if len(cmdLine) < 2 { if len(cmdLine) < 2 {
return reply.MakeArgNumErrReply("_exec") return protocol.MakeArgNumErrReply("_exec")
} }
decoded, err := parseEncodedMultiRawReply(cmdLine[1:]) decoded, err := parseEncodedMultiRawReply(cmdLine[1:])
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
var txCmdLines []CmdLine var txCmdLines []CmdLine
for _, rep := range decoded.Replies { for _, rep := range decoded.Replies {
mbr, ok := rep.(*reply.MultiBulkReply) mbr, ok := rep.(*protocol.MultiBulkReply)
if !ok { if !ok {
return reply.MakeErrReply("exec failed") return protocol.MakeErrReply("exec failed")
} }
txCmdLines = append(txCmdLines, mbr.Args) txCmdLines = append(txCmdLines, mbr.Args)
} }
@@ -122,25 +122,25 @@ func execRelayedMulti(cluster *Cluster, conn redis.Connection, cmdLine CmdLine)
verStr := string(watchCmdLine[i]) verStr := string(watchCmdLine[i])
ver, err := strconv.ParseUint(verStr, 10, 64) ver, err := strconv.ParseUint(verStr, 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("watching command line failed") return protocol.MakeErrReply("watching command line failed")
} }
watching[key] = uint32(ver) watching[key] = uint32(ver)
} }
rawResult := cluster.db.ExecMulti(conn, watching, txCmdLines[1:]) rawResult := cluster.db.ExecMulti(conn, watching, txCmdLines[1:])
_, ok := rawResult.(*reply.EmptyMultiBulkReply) _, ok := rawResult.(*protocol.EmptyMultiBulkReply)
if ok { if ok {
return rawResult return rawResult
} }
resultMBR, ok := rawResult.(*reply.MultiRawReply) resultMBR, ok := rawResult.(*protocol.MultiRawReply)
if !ok { if !ok {
return reply.MakeErrReply("exec failed") return protocol.MakeErrReply("exec failed")
} }
return encodeMultiRawReply(resultMBR) return encodeMultiRawReply(resultMBR)
} }
func execWatch(cluster *Cluster, conn redis.Connection, args [][]byte) redis.Reply { func execWatch(cluster *Cluster, conn redis.Connection, args [][]byte) redis.Reply {
if len(args) < 2 { if len(args) < 2 {
return reply.MakeArgNumErrReply("watch") return protocol.MakeArgNumErrReply("watch")
} }
args = args[1:] args = args[1:]
watching := conn.GetWatching() watching := conn.GetWatching()
@@ -148,14 +148,14 @@ func execWatch(cluster *Cluster, conn redis.Connection, args [][]byte) redis.Rep
key := string(bkey) key := string(bkey)
peer := cluster.peerPicker.PickNode(key) peer := cluster.peerPicker.PickNode(key)
result := cluster.relay(peer, conn, utils.ToCmdLine("GetVer", key)) result := cluster.relay(peer, conn, utils.ToCmdLine("GetVer", key))
if reply.IsErrorReply(result) { if protocol.IsErrorReply(result) {
return result return result
} }
intResult, ok := result.(*reply.IntReply) intResult, ok := result.(*protocol.IntReply)
if !ok { if !ok {
return reply.MakeErrReply("get version failed") return protocol.MakeErrReply("get version failed")
} }
watching[key] = uint32(intResult.Code) watching[key] = uint32(intResult.Code)
} }
return reply.MakeOkReply() return protocol.MakeOkReply()
} }

View File

@@ -4,13 +4,13 @@ import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"github.com/hdt3213/godis/redis/parser" "github.com/hdt3213/godis/redis/parser"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
) )
func encodeCmdLine(cmdLines []CmdLine) [][]byte { func encodeCmdLine(cmdLines []CmdLine) [][]byte {
var result [][]byte var result [][]byte
for _, line := range cmdLines { for _, line := range cmdLines {
raw := reply.MakeMultiBulkReply(line).ToBytes() raw := protocol.MakeMultiBulkReply(line).ToBytes()
encoded := make([]byte, base64.StdEncoding.EncodedLen(len(raw))) encoded := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
base64.StdEncoding.Encode(encoded, raw) base64.StdEncoding.Encode(encoded, raw)
result = append(result, encoded) result = append(result, encoded)
@@ -18,7 +18,7 @@ func encodeCmdLine(cmdLines []CmdLine) [][]byte {
return result return result
} }
func parseEncodedMultiRawReply(args [][]byte) (*reply.MultiRawReply, error) { func parseEncodedMultiRawReply(args [][]byte) (*protocol.MultiRawReply, error) {
cmdBuf := new(bytes.Buffer) cmdBuf := new(bytes.Buffer)
for _, arg := range args { for _, arg := range args {
dbuf := make([]byte, base64.StdEncoding.DecodedLen(len(arg))) dbuf := make([]byte, base64.StdEncoding.DecodedLen(len(arg)))
@@ -30,12 +30,12 @@ func parseEncodedMultiRawReply(args [][]byte) (*reply.MultiRawReply, error) {
} }
cmds, err := parser.ParseBytes(cmdBuf.Bytes()) cmds, err := parser.ParseBytes(cmdBuf.Bytes())
if err != nil { if err != nil {
return nil, reply.MakeErrReply(err.Error()) return nil, protocol.MakeErrReply(err.Error())
} }
return reply.MakeMultiRawReply(cmds), nil return protocol.MakeMultiRawReply(cmds), nil
} }
func encodeMultiRawReply(src *reply.MultiRawReply) *reply.MultiBulkReply { func encodeMultiRawReply(src *protocol.MultiRawReply) *protocol.MultiBulkReply {
args := make([][]byte, 0, len(src.Replies)) args := make([][]byte, 0, len(src.Replies))
for _, rep := range src.Replies { for _, rep := range src.Replies {
raw := rep.ToBytes() raw := rep.ToBytes()
@@ -43,5 +43,5 @@ func encodeMultiRawReply(src *reply.MultiRawReply) *reply.MultiBulkReply {
base64.StdEncoding.Encode(encoded, raw) base64.StdEncoding.Encode(encoded, raw)
args = append(args, encoded) args = append(args, encoded)
} }
return reply.MakeMultiBulkReply(args) return protocol.MakeMultiBulkReply(args)
} }

View File

@@ -3,8 +3,8 @@ package cluster
import ( import (
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )
@@ -35,7 +35,7 @@ func TestEmptyMulti(t *testing.T) {
asserts.AssertNotError(t, result) asserts.AssertNotError(t, result)
result = testCluster.Exec(conn, utils.ToCmdLine("EXEC")) result = testCluster.Exec(conn, utils.ToCmdLine("EXEC"))
asserts.AssertNotError(t, result) asserts.AssertNotError(t, result)
mbr := result.(*reply.MultiRawReply) mbr := result.(*protocol.MultiRawReply)
asserts.AssertStatusReply(t, mbr.Replies[0], "PONG") asserts.AssertStatusReply(t, mbr.Replies[0], "PONG")
} }
@@ -51,7 +51,7 @@ func TestMultiExecOnOthers(t *testing.T) {
cmdLines := conn.GetQueuedCmdLine() cmdLines := conn.GetQueuedCmdLine()
rawResp := execMultiOnOtherNode(testCluster, conn, testCluster.self, nil, cmdLines) rawResp := execMultiOnOtherNode(testCluster, conn, testCluster.self, nil, cmdLines)
rep := rawResp.(*reply.MultiRawReply) rep := rawResp.(*protocol.MultiRawReply)
if len(rep.Replies) != 2 { if len(rep.Replies) != 2 {
t.Errorf("expect 2 replies actual %d", len(rep.Replies)) t.Errorf("expect 2 replies actual %d", len(rep.Replies))
} }

View File

@@ -3,7 +3,7 @@ package cluster
import ( import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
) )
const ( const (
@@ -21,13 +21,13 @@ func Publish(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
var count int64 = 0 var count int64 = 0
results := cluster.broadcast(c, args) results := cluster.broadcast(c, args)
for _, val := range results { for _, val := range results {
if errReply, ok := val.(reply.ErrorReply); ok { if errReply, ok := val.(protocol.ErrorReply); ok {
logger.Error("publish occurs error: " + errReply.Error()) logger.Error("publish occurs error: " + errReply.Error())
} else if intReply, ok := val.(*reply.IntReply); ok { } else if intReply, ok := val.(*protocol.IntReply); ok {
count += intReply.Code count += intReply.Code
} }
} }
return reply.MakeIntReply(count) return protocol.MakeIntReply(count)
} }
// onRelayedPublish receives publish command from peer, just publish to local subscribing clients, do not relay to peers // onRelayedPublish receives publish command from peer, just publish to local subscribing clients, do not relay to peers

View File

@@ -4,7 +4,7 @@ import (
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/parser" "github.com/hdt3213/godis/redis/parser"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )

View File

@@ -2,13 +2,13 @@ package cluster
import ( import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
) )
// Rename renames a key, the origin and the destination must within the same node // Rename renames a key, the origin and the destination must within the same node
func Rename(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply { func Rename(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
if len(args) != 3 { if len(args) != 3 {
return reply.MakeErrReply("ERR wrong number of arguments for 'rename' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'rename' command")
} }
src := string(args[1]) src := string(args[1])
dest := string(args[2]) dest := string(args[2])
@@ -17,7 +17,7 @@ func Rename(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
destPeer := cluster.peerPicker.PickNode(dest) destPeer := cluster.peerPicker.PickNode(dest)
if srcPeer != destPeer { if srcPeer != destPeer {
return reply.MakeErrReply("ERR rename must within one slot in cluster mode") return protocol.MakeErrReply("ERR rename must within one slot in cluster mode")
} }
return cluster.relay(srcPeer, c, args) return cluster.relay(srcPeer, c, args)
} }
@@ -26,7 +26,7 @@ func Rename(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
// The origin and the destination must within the same node // The origin and the destination must within the same node
func RenameNx(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply { func RenameNx(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
if len(args) != 3 { if len(args) != 3 {
return reply.MakeErrReply("ERR wrong number of arguments for 'renamenx' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'renamenx' command")
} }
src := string(args[1]) src := string(args[1])
dest := string(args[2]) dest := string(args[2])
@@ -35,7 +35,7 @@ func RenameNx(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
destPeer := cluster.peerPicker.PickNode(dest) destPeer := cluster.peerPicker.PickNode(dest)
if srcPeer != destPeer { if srcPeer != destPeer {
return reply.MakeErrReply("ERR rename must within one slot in cluster mode") return protocol.MakeErrReply("ERR rename must within one slot in cluster mode")
} }
return cluster.relay(srcPeer, c, args) return cluster.relay(srcPeer, c, args)
} }

View File

@@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )
@@ -18,7 +18,7 @@ func TestRename(t *testing.T) {
newKey := key + utils.RandString(2) newKey := key + utils.RandString(2)
testDB.Exec(conn, utils.ToCmdLine("SET", key, value, "ex", "1000")) testDB.Exec(conn, utils.ToCmdLine("SET", key, value, "ex", "1000"))
result := Rename(testCluster, conn, utils.ToCmdLine("RENAME", key, newKey)) result := Rename(testCluster, conn, utils.ToCmdLine("RENAME", key, newKey))
if _, ok := result.(*reply.OkReply); !ok { if _, ok := result.(*protocol.OkReply); !ok {
t.Error("expect ok") t.Error("expect ok")
return return
} }
@@ -28,9 +28,9 @@ func TestRename(t *testing.T) {
asserts.AssertIntReply(t, result, 1) asserts.AssertIntReply(t, result, 1)
// check ttl // check ttl
result = testDB.Exec(conn, utils.ToCmdLine("TTL", newKey)) result = testDB.Exec(conn, utils.ToCmdLine("TTL", newKey))
intResult, ok := result.(*reply.IntReply) intResult, ok := result.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return return
} }
if intResult.Code <= 0 { if intResult.Code <= 0 {
@@ -55,9 +55,9 @@ func TestRenameNx(t *testing.T) {
asserts.AssertIntReply(t, result, 1) asserts.AssertIntReply(t, result, 1)
result = testDB.Exec(conn, utils.ToCmdLine("TTL", newKey)) result = testDB.Exec(conn, utils.ToCmdLine("TTL", newKey))
intResult, ok := result.(*reply.IntReply) intResult, ok := result.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return return
} }
if intResult.Code <= 0 { if intResult.Code <= 0 {

View File

@@ -117,7 +117,7 @@ func makeRouter() map[string]CmdFunc {
return routerMap return routerMap
} }
// relay command to responsible peer, and return its reply to client // relay command to responsible peer, and return its protocol to client
func defaultFunc(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply { func defaultFunc(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
key := string(args[1]) key := string(args[1])
peer := cluster.peerPicker.PickNode(key) peer := cluster.peerPicker.PickNode(key)

View File

@@ -6,7 +6,7 @@ import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/lib/timewheel" "github.com/hdt3213/godis/lib/timewheel"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@@ -122,7 +122,7 @@ func (tx *Transaction) rollback() error {
// cmdLine: Prepare id cmdName args... // cmdLine: Prepare id cmdName args...
func execPrepare(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply { func execPrepare(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
if len(cmdLine) < 3 { if len(cmdLine) < 3 {
return reply.MakeErrReply("ERR wrong number of arguments for 'prepare' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'prepare' command")
} }
txID := string(cmdLine[1]) txID := string(cmdLine[1])
cmdName := strings.ToLower(string(cmdLine[2])) cmdName := strings.ToLower(string(cmdLine[2]))
@@ -130,46 +130,46 @@ func execPrepare(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Re
cluster.transactions.Put(txID, tx) cluster.transactions.Put(txID, tx)
err := tx.prepare() err := tx.prepare()
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
prepareFunc, ok := prepareFuncMap[cmdName] prepareFunc, ok := prepareFuncMap[cmdName]
if ok { if ok {
return prepareFunc(cluster, c, cmdLine[2:]) return prepareFunc(cluster, c, cmdLine[2:])
} }
return &reply.OkReply{} return &protocol.OkReply{}
} }
// execRollback rollbacks local transaction // execRollback rollbacks local transaction
func execRollback(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply { func execRollback(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
if len(cmdLine) != 2 { if len(cmdLine) != 2 {
return reply.MakeErrReply("ERR wrong number of arguments for 'rollback' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'rollback' command")
} }
txID := string(cmdLine[1]) txID := string(cmdLine[1])
raw, ok := cluster.transactions.Get(txID) raw, ok := cluster.transactions.Get(txID)
if !ok { if !ok {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
tx, _ := raw.(*Transaction) tx, _ := raw.(*Transaction)
err := tx.rollback() err := tx.rollback()
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
// clean transaction // clean transaction
timewheel.Delay(waitBeforeCleanTx, "", func() { timewheel.Delay(waitBeforeCleanTx, "", func() {
cluster.transactions.Remove(tx.id) cluster.transactions.Remove(tx.id)
}) })
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execCommit commits local transaction as a worker when receive execCommit command from coordinator // execCommit commits local transaction as a worker when receive execCommit command from coordinator
func execCommit(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply { func execCommit(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Reply {
if len(cmdLine) != 2 { if len(cmdLine) != 2 {
return reply.MakeErrReply("ERR wrong number of arguments for 'commit' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'commit' command")
} }
txID := string(cmdLine[1]) txID := string(cmdLine[1])
raw, ok := cluster.transactions.Get(txID) raw, ok := cluster.transactions.Get(txID)
if !ok { if !ok {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
tx, _ := raw.(*Transaction) tx, _ := raw.(*Transaction)
@@ -178,10 +178,10 @@ func execCommit(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Rep
result := cluster.db.ExecWithLock(c, tx.cmdLine) result := cluster.db.ExecWithLock(c, tx.cmdLine)
if reply.IsErrorReply(result) { if protocol.IsErrorReply(result) {
// failed // failed
err2 := tx.rollback() err2 := tx.rollback()
return reply.MakeErrReply(fmt.Sprintf("err occurs when rollback: %v, origin err: %s", err2, result)) return protocol.MakeErrReply(fmt.Sprintf("err occurs when rollback: %v, origin err: %s", err2, result))
} }
// after committed // after committed
tx.unLockKeys() tx.unLockKeys()
@@ -195,8 +195,8 @@ func execCommit(cluster *Cluster, c redis.Connection, cmdLine CmdLine) redis.Rep
} }
// requestCommit commands all node to commit transaction as coordinator // requestCommit commands all node to commit transaction as coordinator
func requestCommit(cluster *Cluster, c redis.Connection, txID int64, peers map[string][]string) ([]redis.Reply, reply.ErrorReply) { func requestCommit(cluster *Cluster, c redis.Connection, txID int64, peers map[string][]string) ([]redis.Reply, protocol.ErrorReply) {
var errReply reply.ErrorReply var errReply protocol.ErrorReply
txIDStr := strconv.FormatInt(txID, 10) txIDStr := strconv.FormatInt(txID, 10)
respList := make([]redis.Reply, 0, len(peers)) respList := make([]redis.Reply, 0, len(peers))
for peer := range peers { for peer := range peers {
@@ -206,8 +206,8 @@ func requestCommit(cluster *Cluster, c redis.Connection, txID int64, peers map[s
} else { } else {
resp = cluster.relay(peer, c, makeArgs("commit", txIDStr)) resp = cluster.relay(peer, c, makeArgs("commit", txIDStr))
} }
if reply.IsErrorReply(resp) { if protocol.IsErrorReply(resp) {
errReply = resp.(reply.ErrorReply) errReply = resp.(protocol.ErrorReply)
break break
} }
respList = append(respList, resp) respList = append(respList, resp)

View File

@@ -2,7 +2,7 @@ package cluster
import ( import (
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"math/rand" "math/rand"
"strconv" "strconv"
"testing" "testing"

View File

@@ -6,8 +6,8 @@ import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
@@ -59,9 +59,9 @@ func validateTestData(t *testing.T, db database.DB, dbIndex int, prefix string,
ret = db.Exec(conn, utils.ToCmdLine("GET", key)) ret = db.Exec(conn, utils.ToCmdLine("GET", key))
asserts.AssertBulkReply(t, ret, key) asserts.AssertBulkReply(t, ret, key)
ret = db.Exec(conn, utils.ToCmdLine("TTL", key)) ret = db.Exec(conn, utils.ToCmdLine("TTL", key))
intResult, ok := ret.(*reply.IntReply) intResult, ok := ret.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expected int reply, actually %s", ret.ToBytes()) t.Errorf("expected int protocol, actually %s", ret.ToBytes())
return return
} }
if intResult.Code <= 0 || intResult.Code > 10000 { if intResult.Code <= 0 || intResult.Code > 10000 {

View File

@@ -8,7 +8,7 @@ import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/lib/timewheel" "github.com/hdt3213/godis/lib/timewheel"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strings" "strings"
"sync" "sync"
"time" "time"
@@ -83,28 +83,28 @@ func (db *DB) Exec(c redis.Connection, cmdLine [][]byte) redis.Reply {
cmdName := strings.ToLower(string(cmdLine[0])) cmdName := strings.ToLower(string(cmdLine[0]))
if cmdName == "multi" { if cmdName == "multi" {
if len(cmdLine) != 1 { if len(cmdLine) != 1 {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
return StartMulti(c) return StartMulti(c)
} else if cmdName == "discard" { } else if cmdName == "discard" {
if len(cmdLine) != 1 { if len(cmdLine) != 1 {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
return DiscardMulti(c) return DiscardMulti(c)
} else if cmdName == "exec" { } else if cmdName == "exec" {
if len(cmdLine) != 1 { if len(cmdLine) != 1 {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
return execMulti(db, c) return execMulti(db, c)
} else if cmdName == "watch" { } else if cmdName == "watch" {
if !validateArity(-2, cmdLine) { if !validateArity(-2, cmdLine) {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
return Watch(db, c, cmdLine[1:]) return Watch(db, c, cmdLine[1:])
} }
if c != nil && c.InMultiState() { if c != nil && c.InMultiState() {
EnqueueCmd(c, cmdLine) EnqueueCmd(c, cmdLine)
return reply.MakeQueuedReply() return protocol.MakeQueuedReply()
} }
return db.execNormalCommand(cmdLine) return db.execNormalCommand(cmdLine)
@@ -114,10 +114,10 @@ func (db *DB) execNormalCommand(cmdLine [][]byte) redis.Reply {
cmdName := strings.ToLower(string(cmdLine[0])) cmdName := strings.ToLower(string(cmdLine[0]))
cmd, ok := cmdTable[cmdName] cmd, ok := cmdTable[cmdName]
if !ok { if !ok {
return reply.MakeErrReply("ERR unknown command '" + cmdName + "'") return protocol.MakeErrReply("ERR unknown command '" + cmdName + "'")
} }
if !validateArity(cmd.arity, cmdLine) { if !validateArity(cmd.arity, cmdLine) {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
prepare := cmd.prepare prepare := cmd.prepare

View File

@@ -6,7 +6,7 @@ import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/geohash" "github.com/hdt3213/godis/lib/geohash"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
"strings" "strings"
) )
@@ -14,7 +14,7 @@ import (
// execGeoAdd add a location into SortedSet // execGeoAdd add a location into SortedSet
func execGeoAdd(db *DB, args [][]byte) redis.Reply { func execGeoAdd(db *DB, args [][]byte) redis.Reply {
if len(args) < 4 || len(args)%3 != 1 { if len(args) < 4 || len(args)%3 != 1 {
return reply.MakeErrReply("ERR wrong number of arguments for 'geoadd' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'geoadd' command")
} }
key := string(args[0]) key := string(args[0])
size := (len(args) - 1) / 3 size := (len(args) - 1) / 3
@@ -24,14 +24,14 @@ func execGeoAdd(db *DB, args [][]byte) redis.Reply {
latStr := string(args[3*i+2]) latStr := string(args[3*i+2])
lng, err := strconv.ParseFloat(lngStr, 64) lng, err := strconv.ParseFloat(lngStr, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
lat, err := strconv.ParseFloat(latStr, 64) lat, err := strconv.ParseFloat(latStr, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
if lat < -90 || lat > 90 || lng < -180 || lng > 180 { if lat < -90 || lat > 90 || lng < -180 || lng > 180 {
return reply.MakeErrReply(fmt.Sprintf("ERR invalid longitude,latitude pair %s,%s", latStr, lngStr)) return protocol.MakeErrReply(fmt.Sprintf("ERR invalid longitude,latitude pair %s,%s", latStr, lngStr))
} }
code := float64(geohash.Encode(lat, lng)) code := float64(geohash.Encode(lat, lng))
elements[i] = &sortedset.Element{ elements[i] = &sortedset.Element{
@@ -53,7 +53,7 @@ func execGeoAdd(db *DB, args [][]byte) redis.Reply {
} }
} }
db.addAof(utils.ToCmdLine3("geoadd", args...)) db.addAof(utils.ToCmdLine3("geoadd", args...))
return reply.MakeIntReply(int64(i)) return protocol.MakeIntReply(int64(i))
} }
func undoGeoAdd(db *DB, args [][]byte) []CmdLine { func undoGeoAdd(db *DB, args [][]byte) []CmdLine {
@@ -70,7 +70,7 @@ func undoGeoAdd(db *DB, args [][]byte) []CmdLine {
func execGeoPos(db *DB, args [][]byte) redis.Reply { func execGeoPos(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args) < 1 { if len(args) < 1 {
return reply.MakeErrReply("ERR wrong number of arguments for 'geopos' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'geopos' command")
} }
key := string(args[0]) key := string(args[0])
sortedSet, errReply := db.getAsSortedSet(key) sortedSet, errReply := db.getAsSortedSet(key)
@@ -78,7 +78,7 @@ func execGeoPos(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
positions := make([]redis.Reply, len(args)-1) positions := make([]redis.Reply, len(args)-1)
@@ -86,24 +86,24 @@ func execGeoPos(db *DB, args [][]byte) redis.Reply {
member := string(args[i+1]) member := string(args[i+1])
elem, exists := sortedSet.Get(member) elem, exists := sortedSet.Get(member)
if !exists { if !exists {
positions[i] = &reply.EmptyMultiBulkReply{} positions[i] = &protocol.EmptyMultiBulkReply{}
continue continue
} }
lat, lng := geohash.Decode(uint64(elem.Score)) lat, lng := geohash.Decode(uint64(elem.Score))
lngStr := strconv.FormatFloat(lng, 'f', -1, 64) lngStr := strconv.FormatFloat(lng, 'f', -1, 64)
latStr := strconv.FormatFloat(lat, 'f', -1, 64) latStr := strconv.FormatFloat(lat, 'f', -1, 64)
positions[i] = reply.MakeMultiBulkReply([][]byte{ positions[i] = protocol.MakeMultiBulkReply([][]byte{
[]byte(lngStr), []byte(latStr), []byte(lngStr), []byte(latStr),
}) })
} }
return reply.MakeMultiRawReply(positions) return protocol.MakeMultiRawReply(positions)
} }
// execGeoDist returns the distance between two locations // execGeoDist returns the distance between two locations
func execGeoDist(db *DB, args [][]byte) redis.Reply { func execGeoDist(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args) != 3 && len(args) != 4 { if len(args) != 3 && len(args) != 4 {
return reply.MakeErrReply("ERR wrong number of arguments for 'geodist' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'geodist' command")
} }
key := string(args[0]) key := string(args[0])
sortedSet, errReply := db.getAsSortedSet(key) sortedSet, errReply := db.getAsSortedSet(key)
@@ -111,7 +111,7 @@ func execGeoDist(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
positions := make([][]float64, 2) positions := make([][]float64, 2)
@@ -119,7 +119,7 @@ func execGeoDist(db *DB, args [][]byte) redis.Reply {
member := string(args[i]) member := string(args[i])
elem, exists := sortedSet.Get(member) elem, exists := sortedSet.Get(member)
if !exists { if !exists {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
lat, lng := geohash.Decode(uint64(elem.Score)) lat, lng := geohash.Decode(uint64(elem.Score))
positions[i-1] = []float64{lat, lng} positions[i-1] = []float64{lat, lng}
@@ -132,19 +132,19 @@ func execGeoDist(db *DB, args [][]byte) redis.Reply {
switch unit { switch unit {
case "m": case "m":
disStr := strconv.FormatFloat(dis, 'f', -1, 64) disStr := strconv.FormatFloat(dis, 'f', -1, 64)
return reply.MakeBulkReply([]byte(disStr)) return protocol.MakeBulkReply([]byte(disStr))
case "km": case "km":
disStr := strconv.FormatFloat(dis/1000, 'f', -1, 64) disStr := strconv.FormatFloat(dis/1000, 'f', -1, 64)
return reply.MakeBulkReply([]byte(disStr)) return protocol.MakeBulkReply([]byte(disStr))
} }
return reply.MakeErrReply("ERR unsupported unit provided. please use m, km") return protocol.MakeErrReply("ERR unsupported unit provided. please use m, km")
} }
// execGeoHash return geo-hash-code of given position // execGeoHash return geo-hash-code of given position
func execGeoHash(db *DB, args [][]byte) redis.Reply { func execGeoHash(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args) < 1 { if len(args) < 1 {
return reply.MakeErrReply("ERR wrong number of arguments for 'geohash' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'geohash' command")
} }
key := string(args[0]) key := string(args[0])
@@ -153,7 +153,7 @@ func execGeoHash(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
strs := make([][]byte, len(args)-1) strs := make([][]byte, len(args)-1)
@@ -161,20 +161,20 @@ func execGeoHash(db *DB, args [][]byte) redis.Reply {
member := string(args[i+1]) member := string(args[i+1])
elem, exists := sortedSet.Get(member) elem, exists := sortedSet.Get(member)
if !exists { if !exists {
strs[i] = (&reply.EmptyMultiBulkReply{}).ToBytes() strs[i] = (&protocol.EmptyMultiBulkReply{}).ToBytes()
continue continue
} }
str := geohash.ToString(geohash.FromInt(uint64(elem.Score))) str := geohash.ToString(geohash.FromInt(uint64(elem.Score)))
strs[i] = []byte(str) strs[i] = []byte(str)
} }
return reply.MakeMultiBulkReply(strs) return protocol.MakeMultiBulkReply(strs)
} }
// execGeoRadius returns members within max distance of given point // execGeoRadius returns members within max distance of given point
func execGeoRadius(db *DB, args [][]byte) redis.Reply { func execGeoRadius(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args) < 5 { if len(args) < 5 {
return reply.MakeErrReply("ERR wrong number of arguments for 'georadius' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'georadius' command")
} }
key := string(args[0]) key := string(args[0])
@@ -183,27 +183,27 @@ func execGeoRadius(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
lng, err := strconv.ParseFloat(string(args[1]), 64) lng, err := strconv.ParseFloat(string(args[1]), 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
lat, err := strconv.ParseFloat(string(args[2]), 64) lat, err := strconv.ParseFloat(string(args[2]), 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
radius, err := strconv.ParseFloat(string(args[3]), 64) radius, err := strconv.ParseFloat(string(args[3]), 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
unit := strings.ToLower(string(args[4])) unit := strings.ToLower(string(args[4]))
if unit == "m" { if unit == "m" {
} else if unit == "km" { } else if unit == "km" {
radius *= 1000 radius *= 1000
} else { } else {
return reply.MakeErrReply("ERR unsupported unit provided. please use m, km") return protocol.MakeErrReply("ERR unsupported unit provided. please use m, km")
} }
return geoRadius0(sortedSet, lat, lng, radius) return geoRadius0(sortedSet, lat, lng, radius)
} }
@@ -212,7 +212,7 @@ func execGeoRadius(db *DB, args [][]byte) redis.Reply {
func execGeoRadiusByMember(db *DB, args [][]byte) redis.Reply { func execGeoRadiusByMember(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args) < 3 { if len(args) < 3 {
return reply.MakeErrReply("ERR wrong number of arguments for 'georadiusbymember' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'georadiusbymember' command")
} }
key := string(args[0]) key := string(args[0])
@@ -221,19 +221,19 @@ func execGeoRadiusByMember(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
member := string(args[1]) member := string(args[1])
elem, ok := sortedSet.Get(member) elem, ok := sortedSet.Get(member)
if !ok { if !ok {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
lat, lng := geohash.Decode(uint64(elem.Score)) lat, lng := geohash.Decode(uint64(elem.Score))
radius, err := strconv.ParseFloat(string(args[2]), 64) radius, err := strconv.ParseFloat(string(args[2]), 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
if len(args) > 3 { if len(args) > 3 {
unit := strings.ToLower(string(args[3])) unit := strings.ToLower(string(args[3]))
@@ -241,7 +241,7 @@ func execGeoRadiusByMember(db *DB, args [][]byte) redis.Reply {
} else if unit == "km" { } else if unit == "km" {
radius *= 1000 radius *= 1000
} else { } else {
return reply.MakeErrReply("ERR unsupported unit provided. please use m, km") return protocol.MakeErrReply("ERR unsupported unit provided. please use m, km")
} }
} }
return geoRadius0(sortedSet, lat, lng, radius) return geoRadius0(sortedSet, lat, lng, radius)
@@ -258,7 +258,7 @@ func geoRadius0(sortedSet *sortedset.SortedSet, lat float64, lng float64, radius
members = append(members, []byte(elem.Member)) members = append(members, []byte(elem.Member))
} }
} }
return reply.MakeMultiBulkReply(members) return protocol.MakeMultiBulkReply(members)
} }
func init() { func init() {

View File

@@ -3,8 +3,8 @@ package database
import ( import (
"fmt" "fmt"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"strconv" "strconv"
"testing" "testing"
) )
@@ -72,9 +72,9 @@ func TestGeoDist(t *testing.T) {
"15.087269", "37.502669", pos2, "15.087269", "37.502669", pos2,
)) ))
result := execGeoDist(testDB, utils.ToCmdLine(key, pos1, pos2, "km")) result := execGeoDist(testDB, utils.ToCmdLine(key, pos1, pos2, "km"))
bulkReply, ok := result.(*reply.BulkReply) bulkReply, ok := result.(*protocol.BulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected bulk protocol, actually %s", result.ToBytes()))
return return
} }
dist, err := strconv.ParseFloat(string(bulkReply.Arg), 10) dist, err := strconv.ParseFloat(string(bulkReply.Arg), 10)
@@ -87,9 +87,9 @@ func TestGeoDist(t *testing.T) {
} }
result = execGeoDist(testDB, utils.ToCmdLine(key, pos1, pos2, "m")) result = execGeoDist(testDB, utils.ToCmdLine(key, pos1, pos2, "m"))
bulkReply, ok = result.(*reply.BulkReply) bulkReply, ok = result.(*protocol.BulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected bulk protocol, actually %s", result.ToBytes()))
return return
} }
dist, err = strconv.ParseFloat(string(bulkReply.Arg), 10) dist, err = strconv.ParseFloat(string(bulkReply.Arg), 10)

View File

@@ -5,24 +5,24 @@ import (
"github.com/hdt3213/godis/interface/database" "github.com/hdt3213/godis/interface/database"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"strconv" "strconv"
) )
func (db *DB) getAsDict(key string) (Dict.Dict, reply.ErrorReply) { func (db *DB) getAsDict(key string) (Dict.Dict, protocol.ErrorReply) {
entity, exists := db.GetEntity(key) entity, exists := db.GetEntity(key)
if !exists { if !exists {
return nil, nil return nil, nil
} }
dict, ok := entity.Data.(Dict.Dict) dict, ok := entity.Data.(Dict.Dict)
if !ok { if !ok {
return nil, &reply.WrongTypeErrReply{} return nil, &protocol.WrongTypeErrReply{}
} }
return dict, nil return dict, nil
} }
func (db *DB) getOrInitDict(key string) (dict Dict.Dict, inited bool, errReply reply.ErrorReply) { func (db *DB) getOrInitDict(key string) (dict Dict.Dict, inited bool, errReply protocol.ErrorReply) {
dict, errReply = db.getAsDict(key) dict, errReply = db.getAsDict(key)
if errReply != nil { if errReply != nil {
return nil, false, errReply return nil, false, errReply
@@ -53,7 +53,7 @@ func execHSet(db *DB, args [][]byte) redis.Reply {
result := dict.Put(field, value) result := dict.Put(field, value)
db.addAof(utils.ToCmdLine3("hset", args...)) db.addAof(utils.ToCmdLine3("hset", args...))
return reply.MakeIntReply(int64(result)) return protocol.MakeIntReply(int64(result))
} }
func undoHSet(db *DB, args [][]byte) []CmdLine { func undoHSet(db *DB, args [][]byte) []CmdLine {
@@ -79,7 +79,7 @@ func execHSetNX(db *DB, args [][]byte) redis.Reply {
db.addAof(utils.ToCmdLine3("hsetnx", args...)) db.addAof(utils.ToCmdLine3("hsetnx", args...))
} }
return reply.MakeIntReply(int64(result)) return protocol.MakeIntReply(int64(result))
} }
// execHGet gets field value of hash table // execHGet gets field value of hash table
@@ -94,15 +94,15 @@ func execHGet(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if dict == nil { if dict == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
raw, exists := dict.Get(field) raw, exists := dict.Get(field)
if !exists { if !exists {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
value, _ := raw.([]byte) value, _ := raw.([]byte)
return reply.MakeBulkReply(value) return protocol.MakeBulkReply(value)
} }
// execHExists checks if a hash field exists // execHExists checks if a hash field exists
@@ -117,14 +117,14 @@ func execHExists(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if dict == nil { if dict == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
_, exists := dict.Get(field) _, exists := dict.Get(field)
if exists { if exists {
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
// execHDel deletes a hash field // execHDel deletes a hash field
@@ -143,7 +143,7 @@ func execHDel(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if dict == nil { if dict == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
deleted := 0 deleted := 0
@@ -158,7 +158,7 @@ func execHDel(db *DB, args [][]byte) redis.Reply {
db.addAof(utils.ToCmdLine3("hdel", args...)) db.addAof(utils.ToCmdLine3("hdel", args...))
} }
return reply.MakeIntReply(int64(deleted)) return protocol.MakeIntReply(int64(deleted))
} }
func undoHDel(db *DB, args [][]byte) []CmdLine { func undoHDel(db *DB, args [][]byte) []CmdLine {
@@ -181,16 +181,16 @@ func execHLen(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if dict == nil { if dict == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
return reply.MakeIntReply(int64(dict.Len())) return protocol.MakeIntReply(int64(dict.Len()))
} }
// execHMSet sets multi fields in hash table // execHMSet sets multi fields in hash table
func execHMSet(db *DB, args [][]byte) redis.Reply { func execHMSet(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args)%2 != 1 { if len(args)%2 != 1 {
return reply.MakeSyntaxErrReply() return protocol.MakeSyntaxErrReply()
} }
key := string(args[0]) key := string(args[0])
size := (len(args) - 1) / 2 size := (len(args) - 1) / 2
@@ -213,7 +213,7 @@ func execHMSet(db *DB, args [][]byte) redis.Reply {
dict.Put(field, value) dict.Put(field, value)
} }
db.addAof(utils.ToCmdLine3("hmset", args...)) db.addAof(utils.ToCmdLine3("hmset", args...))
return &reply.OkReply{} return &protocol.OkReply{}
} }
func undoHMSet(db *DB, args [][]byte) []CmdLine { func undoHMSet(db *DB, args [][]byte) []CmdLine {
@@ -242,7 +242,7 @@ func execHMGet(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if dict == nil { if dict == nil {
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
for i, field := range fields { for i, field := range fields {
@@ -254,7 +254,7 @@ func execHMGet(db *DB, args [][]byte) redis.Reply {
result[i] = bytes result[i] = bytes
} }
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
// execHKeys gets all field names in hash table // execHKeys gets all field names in hash table
@@ -266,7 +266,7 @@ func execHKeys(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if dict == nil { if dict == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
fields := make([][]byte, dict.Len()) fields := make([][]byte, dict.Len())
@@ -276,7 +276,7 @@ func execHKeys(db *DB, args [][]byte) redis.Reply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(fields[:i]) return protocol.MakeMultiBulkReply(fields[:i])
} }
// execHVals gets all field value in hash table // execHVals gets all field value in hash table
@@ -289,7 +289,7 @@ func execHVals(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if dict == nil { if dict == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
values := make([][]byte, dict.Len()) values := make([][]byte, dict.Len())
@@ -299,7 +299,7 @@ func execHVals(db *DB, args [][]byte) redis.Reply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(values[:i]) return protocol.MakeMultiBulkReply(values[:i])
} }
// execHGetAll gets all key-value entries in hash table // execHGetAll gets all key-value entries in hash table
@@ -312,7 +312,7 @@ func execHGetAll(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if dict == nil { if dict == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
size := dict.Len() size := dict.Len()
@@ -325,7 +325,7 @@ func execHGetAll(db *DB, args [][]byte) redis.Reply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(result[:i]) return protocol.MakeMultiBulkReply(result[:i])
} }
// execHIncrBy increments the integer value of a hash field by the given number // execHIncrBy increments the integer value of a hash field by the given number
@@ -335,7 +335,7 @@ func execHIncrBy(db *DB, args [][]byte) redis.Reply {
rawDelta := string(args[2]) rawDelta := string(args[2])
delta, err := strconv.ParseInt(rawDelta, 10, 64) delta, err := strconv.ParseInt(rawDelta, 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
dict, _, errReply := db.getOrInitDict(key) dict, _, errReply := db.getOrInitDict(key)
@@ -347,17 +347,17 @@ func execHIncrBy(db *DB, args [][]byte) redis.Reply {
if !exists { if !exists {
dict.Put(field, args[2]) dict.Put(field, args[2])
db.addAof(utils.ToCmdLine3("hincrby", args...)) db.addAof(utils.ToCmdLine3("hincrby", args...))
return reply.MakeBulkReply(args[2]) return protocol.MakeBulkReply(args[2])
} }
val, err := strconv.ParseInt(string(value.([]byte)), 10, 64) val, err := strconv.ParseInt(string(value.([]byte)), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR hash value is not an integer") return protocol.MakeErrReply("ERR hash value is not an integer")
} }
val += delta val += delta
bytes := []byte(strconv.FormatInt(val, 10)) bytes := []byte(strconv.FormatInt(val, 10))
dict.Put(field, bytes) dict.Put(field, bytes)
db.addAof(utils.ToCmdLine3("hincrby", args...)) db.addAof(utils.ToCmdLine3("hincrby", args...))
return reply.MakeBulkReply(bytes) return protocol.MakeBulkReply(bytes)
} }
func undoHIncr(db *DB, args [][]byte) []CmdLine { func undoHIncr(db *DB, args [][]byte) []CmdLine {
@@ -373,7 +373,7 @@ func execHIncrByFloat(db *DB, args [][]byte) redis.Reply {
rawDelta := string(args[2]) rawDelta := string(args[2])
delta, err := decimal.NewFromString(rawDelta) delta, err := decimal.NewFromString(rawDelta)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
// get or init entity // get or init entity
@@ -385,17 +385,17 @@ func execHIncrByFloat(db *DB, args [][]byte) redis.Reply {
value, exists := dict.Get(field) value, exists := dict.Get(field)
if !exists { if !exists {
dict.Put(field, args[2]) dict.Put(field, args[2])
return reply.MakeBulkReply(args[2]) return protocol.MakeBulkReply(args[2])
} }
val, err := decimal.NewFromString(string(value.([]byte))) val, err := decimal.NewFromString(string(value.([]byte)))
if err != nil { if err != nil {
return reply.MakeErrReply("ERR hash value is not a float") return protocol.MakeErrReply("ERR hash value is not a float")
} }
result := val.Add(delta) result := val.Add(delta)
resultBytes := []byte(result.String()) resultBytes := []byte(result.String())
dict.Put(field, resultBytes) dict.Put(field, resultBytes)
db.addAof(utils.ToCmdLine3("hincrbyfloat", args...)) db.addAof(utils.ToCmdLine3("hincrbyfloat", args...))
return reply.MakeBulkReply(resultBytes) return protocol.MakeBulkReply(resultBytes)
} }
func init() { func init() {

View File

@@ -3,8 +3,8 @@ package database
import ( import (
"fmt" "fmt"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"strconv" "strconv"
"testing" "testing"
) )
@@ -21,7 +21,7 @@ func TestHSet(t *testing.T) {
field := strconv.Itoa(i) field := strconv.Itoa(i)
values[field] = []byte(value) values[field] = []byte(value)
result := testDB.Exec(nil, utils.ToCmdLine("hset", key, field, value)) result := testDB.Exec(nil, utils.ToCmdLine("hset", key, field, value))
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(1) { if intResult, _ := result.(*protocol.IntReply); intResult.Code != int64(1) {
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
} }
} }
@@ -29,19 +29,19 @@ func TestHSet(t *testing.T) {
// test hget and hexists // test hget and hexists
for field, v := range values { for field, v := range values {
actual := testDB.Exec(nil, utils.ToCmdLine("hget", key, field)) actual := testDB.Exec(nil, utils.ToCmdLine("hget", key, field))
expected := reply.MakeBulkReply(v) expected := protocol.MakeBulkReply(v)
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(actual.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(actual.ToBytes())))
} }
actual = testDB.Exec(nil, utils.ToCmdLine("hexists", key, field)) actual = testDB.Exec(nil, utils.ToCmdLine("hexists", key, field))
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(1) { if intResult, _ := actual.(*protocol.IntReply); intResult.Code != int64(1) {
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
} }
} }
// test hlen // test hlen
actual := testDB.Exec(nil, utils.ToCmdLine("hlen", key)) actual := testDB.Exec(nil, utils.ToCmdLine("hlen", key))
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(len(values)) { if intResult, _ := actual.(*protocol.IntReply); intResult.Code != int64(len(values)) {
t.Error(fmt.Sprintf("expected %d, actually %d", len(values), intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", len(values), intResult.Code))
} }
} }
@@ -64,12 +64,12 @@ func TestHDel(t *testing.T) {
args := []string{key} args := []string{key}
args = append(args, fields...) args = append(args, fields...)
actual := testDB.Exec(nil, utils.ToCmdLine2("hdel", args...)) actual := testDB.Exec(nil, utils.ToCmdLine2("hdel", args...))
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(len(fields)) { if intResult, _ := actual.(*protocol.IntReply); intResult.Code != int64(len(fields)) {
t.Error(fmt.Sprintf("expected %d, actually %d", len(fields), intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", len(fields), intResult.Code))
} }
actual = testDB.Exec(nil, utils.ToCmdLine("hlen", key)) actual = testDB.Exec(nil, utils.ToCmdLine("hlen", key))
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(0) { if intResult, _ := actual.(*protocol.IntReply); intResult.Code != int64(0) {
t.Error(fmt.Sprintf("expected %d, actually %d", 0, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 0, intResult.Code))
} }
} }
@@ -89,7 +89,7 @@ func TestHMSet(t *testing.T) {
setArgs = append(setArgs, fields[i], values[i]) setArgs = append(setArgs, fields[i], values[i])
} }
result := testDB.Exec(nil, utils.ToCmdLine2("hmset", setArgs...)) result := testDB.Exec(nil, utils.ToCmdLine2("hmset", setArgs...))
if _, ok := result.(*reply.OkReply); !ok { if _, ok := result.(*protocol.OkReply); !ok {
t.Error(fmt.Sprintf("expected ok, actually %s", string(result.ToBytes()))) t.Error(fmt.Sprintf("expected ok, actually %s", string(result.ToBytes())))
} }
@@ -97,7 +97,7 @@ func TestHMSet(t *testing.T) {
getArgs := []string{key} getArgs := []string{key}
getArgs = append(getArgs, fields...) getArgs = append(getArgs, fields...)
actual := testDB.Exec(nil, utils.ToCmdLine2("hmget", getArgs...)) actual := testDB.Exec(nil, utils.ToCmdLine2("hmget", getArgs...))
expected := reply.MakeMultiBulkReply(utils.ToCmdLine(values...)) expected := protocol.MakeMultiBulkReply(utils.ToCmdLine(values...))
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(actual.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(actual.ToBytes())))
} }
@@ -122,7 +122,7 @@ func TestHGetAll(t *testing.T) {
// test HGetAll // test HGetAll
result := testDB.Exec(nil, utils.ToCmdLine("hgetall", key)) result := testDB.Exec(nil, utils.ToCmdLine("hgetall", key))
multiBulk, ok := result.(*reply.MultiBulkReply) multiBulk, ok := result.(*protocol.MultiBulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes()))) t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
} }
@@ -144,7 +144,7 @@ func TestHGetAll(t *testing.T) {
// test HKeys // test HKeys
result = testDB.Exec(nil, utils.ToCmdLine("hkeys", key)) result = testDB.Exec(nil, utils.ToCmdLine("hkeys", key))
multiBulk, ok = result.(*reply.MultiBulkReply) multiBulk, ok = result.(*protocol.MultiBulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes()))) t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
} }
@@ -160,7 +160,7 @@ func TestHGetAll(t *testing.T) {
// test HVals // test HVals
result = testDB.Exec(nil, utils.ToCmdLine("hvals", key)) result = testDB.Exec(nil, utils.ToCmdLine("hvals", key))
multiBulk, ok = result.(*reply.MultiBulkReply) multiBulk, ok = result.(*protocol.MultiBulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes()))) t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
} }
@@ -181,20 +181,20 @@ func TestHIncrBy(t *testing.T) {
key := utils.RandString(10) key := utils.RandString(10)
result := testDB.Exec(nil, utils.ToCmdLine("hincrby", key, "a", "1")) result := testDB.Exec(nil, utils.ToCmdLine("hincrby", key, "a", "1"))
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "1" { if bulkResult, _ := result.(*protocol.BulkReply); string(bulkResult.Arg) != "1" {
t.Error(fmt.Sprintf("expected %s, actually %s", "1", string(bulkResult.Arg))) t.Error(fmt.Sprintf("expected %s, actually %s", "1", string(bulkResult.Arg)))
} }
result = testDB.Exec(nil, utils.ToCmdLine("hincrby", key, "a", "1")) result = testDB.Exec(nil, utils.ToCmdLine("hincrby", key, "a", "1"))
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "2" { if bulkResult, _ := result.(*protocol.BulkReply); string(bulkResult.Arg) != "2" {
t.Error(fmt.Sprintf("expected %s, actually %s", "2", string(bulkResult.Arg))) t.Error(fmt.Sprintf("expected %s, actually %s", "2", string(bulkResult.Arg)))
} }
result = testDB.Exec(nil, utils.ToCmdLine("hincrbyfloat", key, "b", "1.2")) result = testDB.Exec(nil, utils.ToCmdLine("hincrbyfloat", key, "b", "1.2"))
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "1.2" { if bulkResult, _ := result.(*protocol.BulkReply); string(bulkResult.Arg) != "1.2" {
t.Error(fmt.Sprintf("expected %s, actually %s", "1.2", string(bulkResult.Arg))) t.Error(fmt.Sprintf("expected %s, actually %s", "1.2", string(bulkResult.Arg)))
} }
result = testDB.Exec(nil, utils.ToCmdLine("hincrbyfloat", key, "b", "1.2")) result = testDB.Exec(nil, utils.ToCmdLine("hincrbyfloat", key, "b", "1.2"))
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "2.4" { if bulkResult, _ := result.(*protocol.BulkReply); string(bulkResult.Arg) != "2.4" {
t.Error(fmt.Sprintf("expected %s, actually %s", "2.4", string(bulkResult.Arg))) t.Error(fmt.Sprintf("expected %s, actually %s", "2.4", string(bulkResult.Arg)))
} }
} }

View File

@@ -9,7 +9,7 @@ import (
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/lib/wildcard" "github.com/hdt3213/godis/lib/wildcard"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
"time" "time"
) )
@@ -25,7 +25,7 @@ func execDel(db *DB, args [][]byte) redis.Reply {
if deleted > 0 { if deleted > 0 {
db.addAof(utils.ToCmdLine3("del", args...)) db.addAof(utils.ToCmdLine3("del", args...))
} }
return reply.MakeIntReply(int64(deleted)) return protocol.MakeIntReply(int64(deleted))
} }
func undoDel(db *DB, args [][]byte) []CmdLine { func undoDel(db *DB, args [][]byte) []CmdLine {
@@ -46,7 +46,7 @@ func execExists(db *DB, args [][]byte) redis.Reply {
result++ result++
} }
} }
return reply.MakeIntReply(result) return protocol.MakeIntReply(result)
} }
// execExistIn returns existing key in given keys // execExistIn returns existing key in given keys
@@ -62,16 +62,16 @@ func execExistIn(db *DB, args [][]byte) redis.Reply {
} }
} }
if len(result) == 0 { if len(result) == 0 {
return reply.MakeEmptyMultiBulkReply() return protocol.MakeEmptyMultiBulkReply()
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
// execFlushDB removes all data in current db // execFlushDB removes all data in current db
func execFlushDB(db *DB, args [][]byte) redis.Reply { func execFlushDB(db *DB, args [][]byte) redis.Reply {
db.Flush() db.Flush()
db.addAof(utils.ToCmdLine3("flushdb", args...)) db.addAof(utils.ToCmdLine3("flushdb", args...))
return &reply.OkReply{} return &protocol.OkReply{}
} }
// execType returns the type of entity, including: string, list, hash, set and zset // execType returns the type of entity, including: string, list, hash, set and zset
@@ -79,21 +79,21 @@ func execType(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
entity, exists := db.GetEntity(key) entity, exists := db.GetEntity(key)
if !exists { if !exists {
return reply.MakeStatusReply("none") return protocol.MakeStatusReply("none")
} }
switch entity.Data.(type) { switch entity.Data.(type) {
case []byte: case []byte:
return reply.MakeStatusReply("string") return protocol.MakeStatusReply("string")
case *list.LinkedList: case *list.LinkedList:
return reply.MakeStatusReply("list") return protocol.MakeStatusReply("list")
case dict.Dict: case dict.Dict:
return reply.MakeStatusReply("hash") return protocol.MakeStatusReply("hash")
case *set.Set: case *set.Set:
return reply.MakeStatusReply("set") return protocol.MakeStatusReply("set")
case *sortedset.SortedSet: case *sortedset.SortedSet:
return reply.MakeStatusReply("zset") return protocol.MakeStatusReply("zset")
} }
return &reply.UnknownErrReply{} return &protocol.UnknownErrReply{}
} }
func prepareRename(args [][]byte) ([]string, []string) { func prepareRename(args [][]byte) ([]string, []string) {
@@ -105,14 +105,14 @@ func prepareRename(args [][]byte) ([]string, []string) {
// execRename a key // execRename a key
func execRename(db *DB, args [][]byte) redis.Reply { func execRename(db *DB, args [][]byte) redis.Reply {
if len(args) != 2 { if len(args) != 2 {
return reply.MakeErrReply("ERR wrong number of arguments for 'rename' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'rename' command")
} }
src := string(args[0]) src := string(args[0])
dest := string(args[1]) dest := string(args[1])
entity, ok := db.GetEntity(src) entity, ok := db.GetEntity(src)
if !ok { if !ok {
return reply.MakeErrReply("no such key") return protocol.MakeErrReply("no such key")
} }
rawTTL, hasTTL := db.ttlMap.Get(src) rawTTL, hasTTL := db.ttlMap.Get(src)
db.PutEntity(dest, entity) db.PutEntity(dest, entity)
@@ -124,7 +124,7 @@ func execRename(db *DB, args [][]byte) redis.Reply {
db.Expire(dest, expireTime) db.Expire(dest, expireTime)
} }
db.addAof(utils.ToCmdLine3("rename", args...)) db.addAof(utils.ToCmdLine3("rename", args...))
return &reply.OkReply{} return &protocol.OkReply{}
} }
func undoRename(db *DB, args [][]byte) []CmdLine { func undoRename(db *DB, args [][]byte) []CmdLine {
@@ -140,12 +140,12 @@ func execRenameNx(db *DB, args [][]byte) redis.Reply {
_, ok := db.GetEntity(dest) _, ok := db.GetEntity(dest)
if ok { if ok {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
entity, ok := db.GetEntity(src) entity, ok := db.GetEntity(src)
if !ok { if !ok {
return reply.MakeErrReply("no such key") return protocol.MakeErrReply("no such key")
} }
rawTTL, hasTTL := db.ttlMap.Get(src) rawTTL, hasTTL := db.ttlMap.Get(src)
db.Removes(src, dest) // clean src and dest with their ttl db.Removes(src, dest) // clean src and dest with their ttl
@@ -157,7 +157,7 @@ func execRenameNx(db *DB, args [][]byte) redis.Reply {
db.Expire(dest, expireTime) db.Expire(dest, expireTime)
} }
db.addAof(utils.ToCmdLine3("renamenx", args...)) db.addAof(utils.ToCmdLine3("renamenx", args...))
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execExpire sets a key's time to live in seconds // execExpire sets a key's time to live in seconds
@@ -166,19 +166,19 @@ func execExpire(db *DB, args [][]byte) redis.Reply {
ttlArg, err := strconv.ParseInt(string(args[1]), 10, 64) ttlArg, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
ttl := time.Duration(ttlArg) * time.Second ttl := time.Duration(ttlArg) * time.Second
_, exists := db.GetEntity(key) _, exists := db.GetEntity(key)
if !exists { if !exists {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
expireAt := time.Now().Add(ttl) expireAt := time.Now().Add(ttl)
db.Expire(key, expireAt) db.Expire(key, expireAt)
db.addAof(aof.MakeExpireCmd(key, expireAt).Args) db.addAof(aof.MakeExpireCmd(key, expireAt).Args)
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execExpireAt sets a key's expiration in unix timestamp // execExpireAt sets a key's expiration in unix timestamp
@@ -187,18 +187,18 @@ func execExpireAt(db *DB, args [][]byte) redis.Reply {
raw, err := strconv.ParseInt(string(args[1]), 10, 64) raw, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
expireAt := time.Unix(raw, 0) expireAt := time.Unix(raw, 0)
_, exists := db.GetEntity(key) _, exists := db.GetEntity(key)
if !exists { if !exists {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
db.Expire(key, expireAt) db.Expire(key, expireAt)
db.addAof(aof.MakeExpireCmd(key, expireAt).Args) db.addAof(aof.MakeExpireCmd(key, expireAt).Args)
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execPExpire sets a key's time to live in milliseconds // execPExpire sets a key's time to live in milliseconds
@@ -207,19 +207,19 @@ func execPExpire(db *DB, args [][]byte) redis.Reply {
ttlArg, err := strconv.ParseInt(string(args[1]), 10, 64) ttlArg, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
ttl := time.Duration(ttlArg) * time.Millisecond ttl := time.Duration(ttlArg) * time.Millisecond
_, exists := db.GetEntity(key) _, exists := db.GetEntity(key)
if !exists { if !exists {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
expireAt := time.Now().Add(ttl) expireAt := time.Now().Add(ttl)
db.Expire(key, expireAt) db.Expire(key, expireAt)
db.addAof(aof.MakeExpireCmd(key, expireAt).Args) db.addAof(aof.MakeExpireCmd(key, expireAt).Args)
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execPExpireAt sets a key's expiration in unix timestamp specified in milliseconds // execPExpireAt sets a key's expiration in unix timestamp specified in milliseconds
@@ -228,19 +228,19 @@ func execPExpireAt(db *DB, args [][]byte) redis.Reply {
raw, err := strconv.ParseInt(string(args[1]), 10, 64) raw, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
expireAt := time.Unix(0, raw*int64(time.Millisecond)) expireAt := time.Unix(0, raw*int64(time.Millisecond))
_, exists := db.GetEntity(key) _, exists := db.GetEntity(key)
if !exists { if !exists {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
db.Expire(key, expireAt) db.Expire(key, expireAt)
db.addAof(aof.MakeExpireCmd(key, expireAt).Args) db.addAof(aof.MakeExpireCmd(key, expireAt).Args)
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execTTL returns a key's time to live in seconds // execTTL returns a key's time to live in seconds
@@ -248,16 +248,16 @@ func execTTL(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
_, exists := db.GetEntity(key) _, exists := db.GetEntity(key)
if !exists { if !exists {
return reply.MakeIntReply(-2) return protocol.MakeIntReply(-2)
} }
raw, exists := db.ttlMap.Get(key) raw, exists := db.ttlMap.Get(key)
if !exists { if !exists {
return reply.MakeIntReply(-1) return protocol.MakeIntReply(-1)
} }
expireTime, _ := raw.(time.Time) expireTime, _ := raw.(time.Time)
ttl := expireTime.Sub(time.Now()) ttl := expireTime.Sub(time.Now())
return reply.MakeIntReply(int64(ttl / time.Second)) return protocol.MakeIntReply(int64(ttl / time.Second))
} }
// execPTTL returns a key's time to live in milliseconds // execPTTL returns a key's time to live in milliseconds
@@ -265,16 +265,16 @@ func execPTTL(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
_, exists := db.GetEntity(key) _, exists := db.GetEntity(key)
if !exists { if !exists {
return reply.MakeIntReply(-2) return protocol.MakeIntReply(-2)
} }
raw, exists := db.ttlMap.Get(key) raw, exists := db.ttlMap.Get(key)
if !exists { if !exists {
return reply.MakeIntReply(-1) return protocol.MakeIntReply(-1)
} }
expireTime, _ := raw.(time.Time) expireTime, _ := raw.(time.Time)
ttl := expireTime.Sub(time.Now()) ttl := expireTime.Sub(time.Now())
return reply.MakeIntReply(int64(ttl / time.Millisecond)) return protocol.MakeIntReply(int64(ttl / time.Millisecond))
} }
// execPersist removes expiration from a key // execPersist removes expiration from a key
@@ -282,17 +282,17 @@ func execPersist(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
_, exists := db.GetEntity(key) _, exists := db.GetEntity(key)
if !exists { if !exists {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
_, exists = db.ttlMap.Get(key) _, exists = db.ttlMap.Get(key)
if !exists { if !exists {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
db.Persist(key) db.Persist(key)
db.addAof(utils.ToCmdLine3("persist", args...)) db.addAof(utils.ToCmdLine3("persist", args...))
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execKeys returns all keys matching the given pattern // execKeys returns all keys matching the given pattern
@@ -305,18 +305,18 @@ func execKeys(db *DB, args [][]byte) redis.Reply {
} }
return true return true
}) })
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
func toTTLCmd(db *DB, key string) *reply.MultiBulkReply { func toTTLCmd(db *DB, key string) *protocol.MultiBulkReply {
raw, exists := db.ttlMap.Get(key) raw, exists := db.ttlMap.Get(key)
if !exists { if !exists {
// 无 TTL // 无 TTL
return reply.MakeMultiBulkReply(utils.ToCmdLine("PERSIST", key)) return protocol.MakeMultiBulkReply(utils.ToCmdLine("PERSIST", key))
} }
expireTime, _ := raw.(time.Time) expireTime, _ := raw.(time.Time)
timestamp := strconv.FormatInt(expireTime.UnixNano()/1000/1000, 10) timestamp := strconv.FormatInt(expireTime.UnixNano()/1000/1000, 10)
return reply.MakeMultiBulkReply(utils.ToCmdLine("PEXPIREAT", key, timestamp)) return protocol.MakeMultiBulkReply(utils.ToCmdLine("PEXPIREAT", key, timestamp))
} }
func undoExpire(db *DB, args [][]byte) []CmdLine { func undoExpire(db *DB, args [][]byte) []CmdLine {

View File

@@ -3,8 +3,8 @@ package database
import ( import (
"fmt" "fmt"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"strconv" "strconv"
"testing" "testing"
"time" "time"
@@ -73,7 +73,7 @@ func TestRename(t *testing.T) {
newKey := key + utils.RandString(2) newKey := key + utils.RandString(2)
testDB.Exec(nil, utils.ToCmdLine("set", key, value, "ex", "1000")) testDB.Exec(nil, utils.ToCmdLine("set", key, value, "ex", "1000"))
result := testDB.Exec(nil, utils.ToCmdLine("rename", key, newKey)) result := testDB.Exec(nil, utils.ToCmdLine("rename", key, newKey))
if _, ok := result.(*reply.OkReply); !ok { if _, ok := result.(*protocol.OkReply); !ok {
t.Error("expect ok") t.Error("expect ok")
return return
} }
@@ -83,9 +83,9 @@ func TestRename(t *testing.T) {
asserts.AssertIntReply(t, result, 1) asserts.AssertIntReply(t, result, 1)
// check ttl // check ttl
result = testDB.Exec(nil, utils.ToCmdLine("ttl", newKey)) result = testDB.Exec(nil, utils.ToCmdLine("ttl", newKey))
intResult, ok := result.(*reply.IntReply) intResult, ok := result.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return return
} }
if intResult.Code <= 0 { if intResult.Code <= 0 {
@@ -107,9 +107,9 @@ func TestRenameNx(t *testing.T) {
result = testDB.Exec(nil, utils.ToCmdLine("exists", newKey)) result = testDB.Exec(nil, utils.ToCmdLine("exists", newKey))
asserts.AssertIntReply(t, result, 1) asserts.AssertIntReply(t, result, 1)
result = testDB.Exec(nil, utils.ToCmdLine("ttl", newKey)) result = testDB.Exec(nil, utils.ToCmdLine("ttl", newKey))
intResult, ok := result.(*reply.IntReply) intResult, ok := result.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return return
} }
if intResult.Code <= 0 { if intResult.Code <= 0 {
@@ -127,9 +127,9 @@ func TestTTL(t *testing.T) {
result := testDB.Exec(nil, utils.ToCmdLine("expire", key, "1000")) result := testDB.Exec(nil, utils.ToCmdLine("expire", key, "1000"))
asserts.AssertIntReply(t, result, 1) asserts.AssertIntReply(t, result, 1)
result = testDB.Exec(nil, utils.ToCmdLine("ttl", key)) result = testDB.Exec(nil, utils.ToCmdLine("ttl", key))
intResult, ok := result.(*reply.IntReply) intResult, ok := result.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return return
} }
if intResult.Code <= 0 { if intResult.Code <= 0 {
@@ -145,9 +145,9 @@ func TestTTL(t *testing.T) {
result = testDB.Exec(nil, utils.ToCmdLine("PExpire", key, "1000000")) result = testDB.Exec(nil, utils.ToCmdLine("PExpire", key, "1000000"))
asserts.AssertIntReply(t, result, 1) asserts.AssertIntReply(t, result, 1)
result = testDB.Exec(nil, utils.ToCmdLine("PTTL", key)) result = testDB.Exec(nil, utils.ToCmdLine("PTTL", key))
intResult, ok = result.(*reply.IntReply) intResult, ok = result.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return return
} }
if intResult.Code <= 0 { if intResult.Code <= 0 {
@@ -178,9 +178,9 @@ func TestExpireAt(t *testing.T) {
asserts.AssertIntReply(t, result, 1) asserts.AssertIntReply(t, result, 1)
result = testDB.Exec(nil, utils.ToCmdLine("ttl", key)) result = testDB.Exec(nil, utils.ToCmdLine("ttl", key))
intResult, ok := result.(*reply.IntReply) intResult, ok := result.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return return
} }
if intResult.Code <= 0 { if intResult.Code <= 0 {
@@ -192,9 +192,9 @@ func TestExpireAt(t *testing.T) {
result = testDB.Exec(nil, utils.ToCmdLine("PExpireAt", key, strconv.FormatInt(expireAt*1000, 10))) result = testDB.Exec(nil, utils.ToCmdLine("PExpireAt", key, strconv.FormatInt(expireAt*1000, 10)))
asserts.AssertIntReply(t, result, 1) asserts.AssertIntReply(t, result, 1)
result = testDB.Exec(nil, utils.ToCmdLine("ttl", key)) result = testDB.Exec(nil, utils.ToCmdLine("ttl", key))
intResult, ok = result.(*reply.IntReply) intResult, ok = result.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return return
} }
if intResult.Code <= 0 { if intResult.Code <= 0 {

View File

@@ -5,23 +5,23 @@ import (
"github.com/hdt3213/godis/interface/database" "github.com/hdt3213/godis/interface/database"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
) )
func (db *DB) getAsList(key string) (*List.LinkedList, reply.ErrorReply) { func (db *DB) getAsList(key string) (*List.LinkedList, protocol.ErrorReply) {
entity, ok := db.GetEntity(key) entity, ok := db.GetEntity(key)
if !ok { if !ok {
return nil, nil return nil, nil
} }
bytes, ok := entity.Data.(*List.LinkedList) bytes, ok := entity.Data.(*List.LinkedList)
if !ok { if !ok {
return nil, &reply.WrongTypeErrReply{} return nil, &protocol.WrongTypeErrReply{}
} }
return bytes, nil return bytes, nil
} }
func (db *DB) getOrInitList(key string) (list *List.LinkedList, isNew bool, errReply reply.ErrorReply) { func (db *DB) getOrInitList(key string) (list *List.LinkedList, isNew bool, errReply protocol.ErrorReply) {
list, errReply = db.getAsList(key) list, errReply = db.getAsList(key)
if errReply != nil { if errReply != nil {
return nil, false, errReply return nil, false, errReply
@@ -43,7 +43,7 @@ func execLIndex(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
index64, err := strconv.ParseInt(string(args[1]), 10, 64) index64, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
index := int(index64) index := int(index64)
@@ -53,20 +53,20 @@ func execLIndex(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
size := list.Len() // assert: size > 0 size := list.Len() // assert: size > 0
if index < -1*size { if index < -1*size {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} else if index < 0 { } else if index < 0 {
index = size + index index = size + index
} else if index >= size { } else if index >= size {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
val, _ := list.Get(index).([]byte) val, _ := list.Get(index).([]byte)
return reply.MakeBulkReply(val) return protocol.MakeBulkReply(val)
} }
// execLLen gets length of list // execLLen gets length of list
@@ -79,11 +79,11 @@ func execLLen(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
size := int64(list.Len()) size := int64(list.Len())
return reply.MakeIntReply(size) return protocol.MakeIntReply(size)
} }
// execLPop removes the first element of list, and return it // execLPop removes the first element of list, and return it
@@ -97,7 +97,7 @@ func execLPop(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
val, _ := list.Remove(0).([]byte) val, _ := list.Remove(0).([]byte)
@@ -105,7 +105,7 @@ func execLPop(db *DB, args [][]byte) redis.Reply {
db.Remove(key) db.Remove(key)
} }
db.addAof(utils.ToCmdLine3("lpop", args...)) db.addAof(utils.ToCmdLine3("lpop", args...))
return reply.MakeBulkReply(val) return protocol.MakeBulkReply(val)
} }
var lPushCmd = []byte("LPUSH") var lPushCmd = []byte("LPUSH")
@@ -146,7 +146,7 @@ func execLPush(db *DB, args [][]byte) redis.Reply {
} }
db.addAof(utils.ToCmdLine3("lpush", args...)) db.addAof(utils.ToCmdLine3("lpush", args...))
return reply.MakeIntReply(int64(list.Len())) return protocol.MakeIntReply(int64(list.Len()))
} }
func undoLPush(db *DB, args [][]byte) []CmdLine { func undoLPush(db *DB, args [][]byte) []CmdLine {
@@ -170,7 +170,7 @@ func execLPushX(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
// insert // insert
@@ -178,7 +178,7 @@ func execLPushX(db *DB, args [][]byte) redis.Reply {
list.Insert(0, value) list.Insert(0, value)
} }
db.addAof(utils.ToCmdLine3("lpushx", args...)) db.addAof(utils.ToCmdLine3("lpushx", args...))
return reply.MakeIntReply(int64(list.Len())) return protocol.MakeIntReply(int64(list.Len()))
} }
// execLRange gets elements of list in given range // execLRange gets elements of list in given range
@@ -187,12 +187,12 @@ func execLRange(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
start64, err := strconv.ParseInt(string(args[1]), 10, 64) start64, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
start := int(start64) start := int(start64)
stop64, err := strconv.ParseInt(string(args[2]), 10, 64) stop64, err := strconv.ParseInt(string(args[2]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
stop := int(stop64) stop := int(stop64)
@@ -202,7 +202,7 @@ func execLRange(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
// compute index // compute index
@@ -212,7 +212,7 @@ func execLRange(db *DB, args [][]byte) redis.Reply {
} else if start < 0 { } else if start < 0 {
start = size + start start = size + start
} else if start >= size { } else if start >= size {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
if stop < -1*size { if stop < -1*size {
stop = 0 stop = 0
@@ -234,7 +234,7 @@ func execLRange(db *DB, args [][]byte) redis.Reply {
bytes, _ := raw.([]byte) bytes, _ := raw.([]byte)
result[i] = bytes result[i] = bytes
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
// execLRem removes element of list at specified index // execLRem removes element of list at specified index
@@ -243,7 +243,7 @@ func execLRem(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
count64, err := strconv.ParseInt(string(args[1]), 10, 64) count64, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
count := int(count64) count := int(count64)
value := args[2] value := args[2]
@@ -254,7 +254,7 @@ func execLRem(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
var removed int var removed int
@@ -273,7 +273,7 @@ func execLRem(db *DB, args [][]byte) redis.Reply {
db.addAof(utils.ToCmdLine3("lrem", args...)) db.addAof(utils.ToCmdLine3("lrem", args...))
} }
return reply.MakeIntReply(int64(removed)) return protocol.MakeIntReply(int64(removed))
} }
// execLSet puts element at specified index of list // execLSet puts element at specified index of list
@@ -282,7 +282,7 @@ func execLSet(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
index64, err := strconv.ParseInt(string(args[1]), 10, 64) index64, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
index := int(index64) index := int(index64)
value := args[2] value := args[2]
@@ -293,21 +293,21 @@ func execLSet(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return reply.MakeErrReply("ERR no such key") return protocol.MakeErrReply("ERR no such key")
} }
size := list.Len() // assert: size > 0 size := list.Len() // assert: size > 0
if index < -1*size { if index < -1*size {
return reply.MakeErrReply("ERR index out of range") return protocol.MakeErrReply("ERR index out of range")
} else if index < 0 { } else if index < 0 {
index = size + index index = size + index
} else if index >= size { } else if index >= size {
return reply.MakeErrReply("ERR index out of range") return protocol.MakeErrReply("ERR index out of range")
} }
list.Set(index, value) list.Set(index, value)
db.addAof(utils.ToCmdLine3("lset", args...)) db.addAof(utils.ToCmdLine3("lset", args...))
return &reply.OkReply{} return &protocol.OkReply{}
} }
func undoLSet(db *DB, args [][]byte) []CmdLine { func undoLSet(db *DB, args [][]byte) []CmdLine {
@@ -354,7 +354,7 @@ func execRPop(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
val, _ := list.RemoveLast().([]byte) val, _ := list.RemoveLast().([]byte)
@@ -362,7 +362,7 @@ func execRPop(db *DB, args [][]byte) redis.Reply {
db.Remove(key) db.Remove(key)
} }
db.addAof(utils.ToCmdLine3("rpop", args...)) db.addAof(utils.ToCmdLine3("rpop", args...))
return reply.MakeBulkReply(val) return protocol.MakeBulkReply(val)
} }
var rPushCmd = []byte("RPUSH") var rPushCmd = []byte("RPUSH")
@@ -404,7 +404,7 @@ func execRPopLPush(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sourceList == nil { if sourceList == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
// get dest entity // get dest entity
@@ -422,7 +422,7 @@ func execRPopLPush(db *DB, args [][]byte) redis.Reply {
} }
db.addAof(utils.ToCmdLine3("rpoplpush", args...)) db.addAof(utils.ToCmdLine3("rpoplpush", args...))
return reply.MakeBulkReply(val) return protocol.MakeBulkReply(val)
} }
func undoRPopLPush(db *DB, args [][]byte) []CmdLine { func undoRPopLPush(db *DB, args [][]byte) []CmdLine {
@@ -465,7 +465,7 @@ func execRPush(db *DB, args [][]byte) redis.Reply {
list.Add(value) list.Add(value)
} }
db.addAof(utils.ToCmdLine3("rpush", args...)) db.addAof(utils.ToCmdLine3("rpush", args...))
return reply.MakeIntReply(int64(list.Len())) return protocol.MakeIntReply(int64(list.Len()))
} }
func undoRPush(db *DB, args [][]byte) []CmdLine { func undoRPush(db *DB, args [][]byte) []CmdLine {
@@ -481,7 +481,7 @@ func undoRPush(db *DB, args [][]byte) []CmdLine {
// execRPushX inserts element at last of list only if list exists // execRPushX inserts element at last of list only if list exists
func execRPushX(db *DB, args [][]byte) redis.Reply { func execRPushX(db *DB, args [][]byte) redis.Reply {
if len(args) < 2 { if len(args) < 2 {
return reply.MakeErrReply("ERR wrong number of arguments for 'rpush' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'rpush' command")
} }
key := string(args[0]) key := string(args[0])
values := args[1:] values := args[1:]
@@ -492,7 +492,7 @@ func execRPushX(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if list == nil { if list == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
// put list // put list
@@ -501,7 +501,7 @@ func execRPushX(db *DB, args [][]byte) redis.Reply {
} }
db.addAof(utils.ToCmdLine3("rpushx", args...)) db.addAof(utils.ToCmdLine3("rpushx", args...))
return reply.MakeIntReply(int64(list.Len())) return protocol.MakeIntReply(int64(list.Len()))
} }
func init() { func init() {

View File

@@ -3,8 +3,8 @@ package database
import ( import (
"fmt" "fmt"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"strconv" "strconv"
"testing" "testing"
) )
@@ -20,12 +20,12 @@ func TestPush(t *testing.T) {
value := utils.RandString(10) value := utils.RandString(10)
values[i] = []byte(value) values[i] = []byte(value)
result := testDB.Exec(nil, utils.ToCmdLine("rpush", key, value)) result := testDB.Exec(nil, utils.ToCmdLine("rpush", key, value))
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(i+1) { if intResult, _ := result.(*protocol.IntReply); intResult.Code != int64(i+1) {
t.Error(fmt.Sprintf("expected %d, actually %d", i+1, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", i+1, intResult.Code))
} }
} }
actual := testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1")) actual := testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
expected := reply.MakeMultiBulkReply(values) expected := protocol.MakeMultiBulkReply(values)
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("push error") t.Error("push error")
} }
@@ -42,11 +42,11 @@ func TestPush(t *testing.T) {
args[i+1] = value args[i+1] = value
} }
result := testDB.Exec(nil, utils.ToCmdLine2("rpush", args...)) result := testDB.Exec(nil, utils.ToCmdLine2("rpush", args...))
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) { if intResult, _ := result.(*protocol.IntReply); intResult.Code != int64(size) {
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
} }
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1")) actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
expected = reply.MakeMultiBulkReply(values) expected = protocol.MakeMultiBulkReply(values)
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("push error") t.Error("push error")
} }
@@ -59,12 +59,12 @@ func TestPush(t *testing.T) {
value := utils.RandString(10) value := utils.RandString(10)
values[size-i-1] = []byte(value) values[size-i-1] = []byte(value)
result = testDB.Exec(nil, utils.ToCmdLine("lpush", key, value)) result = testDB.Exec(nil, utils.ToCmdLine("lpush", key, value))
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(i+1) { if intResult, _ := result.(*protocol.IntReply); intResult.Code != int64(i+1) {
t.Error(fmt.Sprintf("expected %d, actually %d", i+1, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", i+1, intResult.Code))
} }
} }
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1")) actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
expected = reply.MakeMultiBulkReply(values) expected = protocol.MakeMultiBulkReply(values)
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("push error") t.Error("push error")
} }
@@ -82,11 +82,11 @@ func TestPush(t *testing.T) {
} }
result = execLPush(testDB, values) result = execLPush(testDB, values)
result = testDB.Exec(nil, utils.ToCmdLine2("lpush", args...)) result = testDB.Exec(nil, utils.ToCmdLine2("lpush", args...))
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) { if intResult, _ := result.(*protocol.IntReply); intResult.Code != int64(size) {
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
} }
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1")) actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
expected = reply.MakeMultiBulkReply(expectedValues) expected = protocol.MakeMultiBulkReply(expectedValues)
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("push error") t.Error("push error")
} }
@@ -108,7 +108,7 @@ func TestLRange(t *testing.T) {
start := "0" start := "0"
end := "9" end := "9"
actual := testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end)) actual := testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
expected := reply.MakeMultiBulkReply(values[0:10]) expected := protocol.MakeMultiBulkReply(values[0:10])
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("range error [%s, %s]", start, end)) t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
} }
@@ -116,7 +116,7 @@ func TestLRange(t *testing.T) {
start = "0" start = "0"
end = "200" end = "200"
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end)) actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
expected = reply.MakeMultiBulkReply(values) expected = protocol.MakeMultiBulkReply(values)
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("range error [%s, %s]", start, end)) t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
} }
@@ -124,7 +124,7 @@ func TestLRange(t *testing.T) {
start = "0" start = "0"
end = "-10" end = "-10"
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end)) actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
expected = reply.MakeMultiBulkReply(values[0 : size-10+1]) expected = protocol.MakeMultiBulkReply(values[0 : size-10+1])
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("range error [%s, %s]", start, end)) t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
} }
@@ -132,7 +132,7 @@ func TestLRange(t *testing.T) {
start = "0" start = "0"
end = "-200" end = "-200"
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end)) actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
expected = reply.MakeMultiBulkReply(values[0:0]) expected = protocol.MakeMultiBulkReply(values[0:0])
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("range error [%s, %s]", start, end)) t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
} }
@@ -140,7 +140,7 @@ func TestLRange(t *testing.T) {
start = "-10" start = "-10"
end = "-1" end = "-1"
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end)) actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
expected = reply.MakeMultiBulkReply(values[90:]) expected = protocol.MakeMultiBulkReply(values[90:])
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("range error [%s, %s]", start, end)) t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
} }
@@ -159,13 +159,13 @@ func TestLIndex(t *testing.T) {
} }
result := testDB.Exec(nil, utils.ToCmdLine("llen", key)) result := testDB.Exec(nil, utils.ToCmdLine("llen", key))
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) { if intResult, _ := result.(*protocol.IntReply); intResult.Code != int64(size) {
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
} }
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, strconv.Itoa(i))) result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, strconv.Itoa(i)))
expected := reply.MakeBulkReply(values[i]) expected := protocol.MakeBulkReply(values[i])
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -173,7 +173,7 @@ func TestLIndex(t *testing.T) {
for i := 1; i <= size; i++ { for i := 1; i <= size; i++ {
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, strconv.Itoa(-i))) result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, strconv.Itoa(-i)))
expected := reply.MakeBulkReply(values[size-i]) expected := protocol.MakeBulkReply(values[size-i])
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -188,29 +188,29 @@ func TestLRem(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("rpush", values...)) testDB.Exec(nil, utils.ToCmdLine2("rpush", values...))
result := testDB.Exec(nil, utils.ToCmdLine("lrem", key, "1", "a")) result := testDB.Exec(nil, utils.ToCmdLine("lrem", key, "1", "a"))
if intResult, _ := result.(*reply.IntReply); intResult.Code != 1 { if intResult, _ := result.(*protocol.IntReply); intResult.Code != 1 {
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
} }
result = testDB.Exec(nil, utils.ToCmdLine("llen", key)) result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
if intResult, _ := result.(*reply.IntReply); intResult.Code != 6 { if intResult, _ := result.(*protocol.IntReply); intResult.Code != 6 {
t.Error(fmt.Sprintf("expected %d, actually %d", 6, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 6, intResult.Code))
} }
result = testDB.Exec(nil, utils.ToCmdLine("lrem", key, "-2", "a")) result = testDB.Exec(nil, utils.ToCmdLine("lrem", key, "-2", "a"))
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 { if intResult, _ := result.(*protocol.IntReply); intResult.Code != 2 {
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
} }
result = testDB.Exec(nil, utils.ToCmdLine("llen", key)) result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
if intResult, _ := result.(*reply.IntReply); intResult.Code != 4 { if intResult, _ := result.(*protocol.IntReply); intResult.Code != 4 {
t.Error(fmt.Sprintf("expected %d, actually %d", 4, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 4, intResult.Code))
} }
result = testDB.Exec(nil, utils.ToCmdLine("lrem", key, "0", "a")) result = testDB.Exec(nil, utils.ToCmdLine("lrem", key, "0", "a"))
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 { if intResult, _ := result.(*protocol.IntReply); intResult.Code != 2 {
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
} }
result = testDB.Exec(nil, utils.ToCmdLine("llen", key)) result = testDB.Exec(nil, utils.ToCmdLine("llen", key))
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 { if intResult, _ := result.(*protocol.IntReply); intResult.Code != 2 {
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code)) t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
} }
} }
@@ -227,11 +227,11 @@ func TestLSet(t *testing.T) {
indexStr := strconv.Itoa(i) indexStr := strconv.Itoa(i)
value := utils.RandString(10) value := utils.RandString(10)
result := testDB.Exec(nil, utils.ToCmdLine("lset", key, indexStr, value)) result := testDB.Exec(nil, utils.ToCmdLine("lset", key, indexStr, value))
if _, ok := result.(*reply.OkReply); !ok { if _, ok := result.(*protocol.OkReply); !ok {
t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes()))) t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes())))
} }
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, indexStr)) result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, indexStr))
expected := reply.MakeBulkReply([]byte(value)) expected := protocol.MakeBulkReply([]byte(value))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -240,11 +240,11 @@ func TestLSet(t *testing.T) {
for i := 1; i <= size; i++ { for i := 1; i <= size; i++ {
value := utils.RandString(10) value := utils.RandString(10)
result := testDB.Exec(nil, utils.ToCmdLine("lset", key, strconv.Itoa(-i), value)) result := testDB.Exec(nil, utils.ToCmdLine("lset", key, strconv.Itoa(-i), value))
if _, ok := result.(*reply.OkReply); !ok { if _, ok := result.(*protocol.OkReply); !ok {
t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes()))) t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes())))
} }
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, strconv.Itoa(len(values)-i-1))) result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, strconv.Itoa(len(values)-i-1)))
expected := reply.MakeBulkReply([]byte(value)) expected := protocol.MakeBulkReply([]byte(value))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -253,7 +253,7 @@ func TestLSet(t *testing.T) {
// test illegal index // test illegal index
value := utils.RandString(10) value := utils.RandString(10)
result := testDB.Exec(nil, utils.ToCmdLine("lset", key, strconv.Itoa(-len(values)-1), value)) result := testDB.Exec(nil, utils.ToCmdLine("lset", key, strconv.Itoa(-len(values)-1), value))
expected := reply.MakeErrReply("ERR index out of range") expected := protocol.MakeErrReply("ERR index out of range")
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -262,7 +262,7 @@ func TestLSet(t *testing.T) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
result = testDB.Exec(nil, utils.ToCmdLine("lset", key, "a", value)) result = testDB.Exec(nil, utils.ToCmdLine("lset", key, "a", value))
expected = reply.MakeErrReply("ERR value is not an integer or out of range") expected = protocol.MakeErrReply("ERR value is not an integer or out of range")
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -277,13 +277,13 @@ func TestLPop(t *testing.T) {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
result := testDB.Exec(nil, utils.ToCmdLine("lpop", key)) result := testDB.Exec(nil, utils.ToCmdLine("lpop", key))
expected := reply.MakeBulkReply([]byte(values[i+1])) expected := protocol.MakeBulkReply([]byte(values[i+1]))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
} }
result := testDB.Exec(nil, utils.ToCmdLine("rpop", key)) result := testDB.Exec(nil, utils.ToCmdLine("rpop", key))
expected := &reply.NullBulkReply{} expected := &protocol.NullBulkReply{}
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -298,13 +298,13 @@ func TestRPop(t *testing.T) {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
result := testDB.Exec(nil, utils.ToCmdLine("rpop", key)) result := testDB.Exec(nil, utils.ToCmdLine("rpop", key))
expected := reply.MakeBulkReply([]byte(values[len(values)-i-1])) expected := protocol.MakeBulkReply([]byte(values[len(values)-i-1]))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
} }
result := testDB.Exec(nil, utils.ToCmdLine("rpop", key)) result := testDB.Exec(nil, utils.ToCmdLine("rpop", key))
expected := &reply.NullBulkReply{} expected := &protocol.NullBulkReply{}
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -320,7 +320,7 @@ func TestRPopLPush(t *testing.T) {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
result := testDB.Exec(nil, utils.ToCmdLine("rpoplpush", key1, key2)) result := testDB.Exec(nil, utils.ToCmdLine("rpoplpush", key1, key2))
expected := reply.MakeBulkReply([]byte(values[len(values)-i-1])) expected := protocol.MakeBulkReply([]byte(values[len(values)-i-1]))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -330,7 +330,7 @@ func TestRPopLPush(t *testing.T) {
} }
} }
result := testDB.Exec(nil, utils.ToCmdLine("rpop", key1)) result := testDB.Exec(nil, utils.ToCmdLine("rpop", key1))
expected := &reply.NullBulkReply{} expected := &protocol.NullBulkReply{}
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -340,7 +340,7 @@ func TestRPushX(t *testing.T) {
testDB.Flush() testDB.Flush()
key := utils.RandString(10) key := utils.RandString(10)
result := testDB.Exec(nil, utils.ToCmdLine("rpushx", key, "1")) result := testDB.Exec(nil, utils.ToCmdLine("rpushx", key, "1"))
expected := reply.MakeIntReply(int64(0)) expected := protocol.MakeIntReply(int64(0))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -349,12 +349,12 @@ func TestRPushX(t *testing.T) {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
value := utils.RandString(10) value := utils.RandString(10)
result = testDB.Exec(nil, utils.ToCmdLine("rpushx", key, value)) result = testDB.Exec(nil, utils.ToCmdLine("rpushx", key, value))
expected := reply.MakeIntReply(int64(i + 2)) expected := protocol.MakeIntReply(int64(i + 2))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, "-1")) result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, "-1"))
expected2 := reply.MakeBulkReply([]byte(value)) expected2 := protocol.MakeBulkReply([]byte(value))
if !utils.BytesEquals(result.ToBytes(), expected2.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected2.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes())))
} }
@@ -365,7 +365,7 @@ func TestLPushX(t *testing.T) {
testDB.Flush() testDB.Flush()
key := utils.RandString(10) key := utils.RandString(10)
result := testDB.Exec(nil, utils.ToCmdLine("rpushx", key, "1")) result := testDB.Exec(nil, utils.ToCmdLine("rpushx", key, "1"))
expected := reply.MakeIntReply(int64(0)) expected := protocol.MakeIntReply(int64(0))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
@@ -374,12 +374,12 @@ func TestLPushX(t *testing.T) {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
value := utils.RandString(10) value := utils.RandString(10)
result = testDB.Exec(nil, utils.ToCmdLine("lpushx", key, value)) result = testDB.Exec(nil, utils.ToCmdLine("lpushx", key, value))
expected := reply.MakeIntReply(int64(i + 2)) expected := protocol.MakeIntReply(int64(i + 2))
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
} }
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, "0")) result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, "0"))
expected2 := reply.MakeBulkReply([]byte(value)) expected2 := protocol.MakeBulkReply([]byte(value))
if !utils.BytesEquals(result.ToBytes(), expected2.ToBytes()) { if !utils.BytesEquals(result.ToBytes(), expected2.ToBytes()) {
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes()))) t.Error(fmt.Sprintf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes())))
} }

View File

@@ -9,7 +9,7 @@ import (
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/pubsub" "github.com/hdt3213/godis/pubsub"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"strings" "strings"
@@ -74,7 +74,7 @@ func (mdb *MultiDB) Exec(c redis.Connection, cmdLine [][]byte) (result redis.Rep
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
logger.Warn(fmt.Sprintf("error occurs: %v\n%s", err, string(debug.Stack()))) logger.Warn(fmt.Sprintf("error occurs: %v\n%s", err, string(debug.Stack())))
result = &reply.UnknownErrReply{} result = &protocol.UnknownErrReply{}
} }
}() }()
@@ -84,13 +84,13 @@ func (mdb *MultiDB) Exec(c redis.Connection, cmdLine [][]byte) (result redis.Rep
return Auth(c, cmdLine[1:]) return Auth(c, cmdLine[1:])
} }
if !isAuthenticated(c) { if !isAuthenticated(c) {
return reply.MakeErrReply("NOAUTH Authentication required") return protocol.MakeErrReply("NOAUTH Authentication required")
} }
// special commands // special commands
if cmdName == "subscribe" { if cmdName == "subscribe" {
if len(cmdLine) < 2 { if len(cmdLine) < 2 {
return reply.MakeArgNumErrReply("subscribe") return protocol.MakeArgNumErrReply("subscribe")
} }
return pubsub.Subscribe(mdb.hub, c, cmdLine[1:]) return pubsub.Subscribe(mdb.hub, c, cmdLine[1:])
} else if cmdName == "publish" { } else if cmdName == "publish" {
@@ -106,10 +106,10 @@ func (mdb *MultiDB) Exec(c redis.Connection, cmdLine [][]byte) (result redis.Rep
return mdb.flushAll() return mdb.flushAll()
} else if cmdName == "select" { } else if cmdName == "select" {
if c != nil && c.InMultiState() { if c != nil && c.InMultiState() {
return reply.MakeErrReply("cannot select database within multi") return protocol.MakeErrReply("cannot select database within multi")
} }
if len(cmdLine) != 2 { if len(cmdLine) != 2 {
return reply.MakeArgNumErrReply("select") return protocol.MakeArgNumErrReply("select")
} }
return execSelect(c, mdb, cmdLine[1:]) return execSelect(c, mdb, cmdLine[1:])
} }
@@ -118,7 +118,7 @@ func (mdb *MultiDB) Exec(c redis.Connection, cmdLine [][]byte) (result redis.Rep
// normal commands // normal commands
dbIndex := c.GetDBIndex() dbIndex := c.GetDBIndex()
if dbIndex >= len(mdb.dbSet) { if dbIndex >= len(mdb.dbSet) {
return reply.MakeErrReply("ERR DB index is out of range") return protocol.MakeErrReply("ERR DB index is out of range")
} }
selectedDB := mdb.dbSet[dbIndex] selectedDB := mdb.dbSet[dbIndex]
return selectedDB.Exec(c, cmdLine) return selectedDB.Exec(c, cmdLine)
@@ -139,13 +139,13 @@ func (mdb *MultiDB) Close() {
func execSelect(c redis.Connection, mdb *MultiDB, args [][]byte) redis.Reply { func execSelect(c redis.Connection, mdb *MultiDB, args [][]byte) redis.Reply {
dbIndex, err := strconv.Atoi(string(args[0])) dbIndex, err := strconv.Atoi(string(args[0]))
if err != nil { if err != nil {
return reply.MakeErrReply("ERR invalid DB index") return protocol.MakeErrReply("ERR invalid DB index")
} }
if dbIndex >= len(mdb.dbSet) { if dbIndex >= len(mdb.dbSet) {
return reply.MakeErrReply("ERR DB index is out of range") return protocol.MakeErrReply("ERR DB index is out of range")
} }
c.SelectDB(dbIndex) c.SelectDB(dbIndex)
return reply.MakeOkReply() return protocol.MakeOkReply()
} }
func (mdb *MultiDB) flushAll() redis.Reply { func (mdb *MultiDB) flushAll() redis.Reply {
@@ -155,7 +155,7 @@ func (mdb *MultiDB) flushAll() redis.Reply {
if mdb.aofHandler != nil { if mdb.aofHandler != nil {
mdb.aofHandler.AddAof(0, utils.ToCmdLine("FlushAll")) mdb.aofHandler.AddAof(0, utils.ToCmdLine("FlushAll"))
} }
return &reply.OkReply{} return &protocol.OkReply{}
} }
// ForEach traverses all the keys in the given database // ForEach traverses all the keys in the given database
@@ -170,7 +170,7 @@ func (mdb *MultiDB) ForEach(dbIndex int, cb func(key string, data *database.Data
// ExecMulti executes multi commands transaction Atomically and Isolated // ExecMulti executes multi commands transaction Atomically and Isolated
func (mdb *MultiDB) ExecMulti(conn redis.Connection, watching map[string]uint32, cmdLines []CmdLine) redis.Reply { func (mdb *MultiDB) ExecMulti(conn redis.Connection, watching map[string]uint32, cmdLines []CmdLine) redis.Reply {
if conn.GetDBIndex() >= len(mdb.dbSet) { if conn.GetDBIndex() >= len(mdb.dbSet) {
return reply.MakeErrReply("ERR DB index is out of range") return protocol.MakeErrReply("ERR DB index is out of range")
} }
db := mdb.dbSet[conn.GetDBIndex()] db := mdb.dbSet[conn.GetDBIndex()]
return db.ExecMulti(conn, watching, cmdLines) return db.ExecMulti(conn, watching, cmdLines)
@@ -215,11 +215,11 @@ func (mdb *MultiDB) ExecWithLock(conn redis.Connection, cmdLine [][]byte) redis.
// BGRewriteAOF asynchronously rewrites Append-Only-File // BGRewriteAOF asynchronously rewrites Append-Only-File
func BGRewriteAOF(db *MultiDB, args [][]byte) redis.Reply { func BGRewriteAOF(db *MultiDB, args [][]byte) redis.Reply {
go db.aofHandler.Rewrite() go db.aofHandler.Rewrite()
return reply.MakeStatusReply("Background append only file rewriting started") return protocol.MakeStatusReply("Background append only file rewriting started")
} }
// RewriteAOF start Append-Only-File rewriting and blocked until it finished // RewriteAOF start Append-Only-File rewriting and blocked until it finished
func RewriteAOF(db *MultiDB, args [][]byte) redis.Reply { func RewriteAOF(db *MultiDB, args [][]byte) redis.Reply {
db.aofHandler.Rewrite() db.aofHandler.Rewrite()
return reply.MakeStatusReply("Background append only file rewriting started") return protocol.MakeStatusReply("Background append only file rewriting started")
} }

View File

@@ -5,23 +5,23 @@ import (
"github.com/hdt3213/godis/interface/database" "github.com/hdt3213/godis/interface/database"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
) )
func (db *DB) getAsSet(key string) (*HashSet.Set, reply.ErrorReply) { func (db *DB) getAsSet(key string) (*HashSet.Set, protocol.ErrorReply) {
entity, exists := db.GetEntity(key) entity, exists := db.GetEntity(key)
if !exists { if !exists {
return nil, nil return nil, nil
} }
set, ok := entity.Data.(*HashSet.Set) set, ok := entity.Data.(*HashSet.Set)
if !ok { if !ok {
return nil, &reply.WrongTypeErrReply{} return nil, &protocol.WrongTypeErrReply{}
} }
return set, nil return set, nil
} }
func (db *DB) getOrInitSet(key string) (set *HashSet.Set, inited bool, errReply reply.ErrorReply) { func (db *DB) getOrInitSet(key string) (set *HashSet.Set, inited bool, errReply protocol.ErrorReply) {
set, errReply = db.getAsSet(key) set, errReply = db.getAsSet(key)
if errReply != nil { if errReply != nil {
return nil, false, errReply return nil, false, errReply
@@ -52,7 +52,7 @@ func execSAdd(db *DB, args [][]byte) redis.Reply {
counter += set.Add(string(member)) counter += set.Add(string(member))
} }
db.addAof(utils.ToCmdLine3("sadd", args...)) db.addAof(utils.ToCmdLine3("sadd", args...))
return reply.MakeIntReply(int64(counter)) return protocol.MakeIntReply(int64(counter))
} }
// execSIsMember checks if the given value is member of set // execSIsMember checks if the given value is member of set
@@ -66,14 +66,14 @@ func execSIsMember(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if set == nil { if set == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
has := set.Has(member) has := set.Has(member)
if has { if has {
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
// execSRem removes a member from set // execSRem removes a member from set
@@ -86,7 +86,7 @@ func execSRem(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if set == nil { if set == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
counter := 0 counter := 0
for _, member := range members { for _, member := range members {
@@ -98,7 +98,7 @@ func execSRem(db *DB, args [][]byte) redis.Reply {
if counter > 0 { if counter > 0 {
db.addAof(utils.ToCmdLine3("srem", args...)) db.addAof(utils.ToCmdLine3("srem", args...))
} }
return reply.MakeIntReply(int64(counter)) return protocol.MakeIntReply(int64(counter))
} }
// execSCard gets the number of members in a set // execSCard gets the number of members in a set
@@ -111,9 +111,9 @@ func execSCard(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if set == nil { if set == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
return reply.MakeIntReply(int64(set.Len())) return protocol.MakeIntReply(int64(set.Len()))
} }
// execSMembers gets all members in a set // execSMembers gets all members in a set
@@ -126,7 +126,7 @@ func execSMembers(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if set == nil { if set == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
arr := make([][]byte, set.Len()) arr := make([][]byte, set.Len())
@@ -136,7 +136,7 @@ func execSMembers(db *DB, args [][]byte) redis.Reply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(arr) return protocol.MakeMultiBulkReply(arr)
} }
// execSInter intersect multiple sets // execSInter intersect multiple sets
@@ -153,7 +153,7 @@ func execSInter(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if set == nil { if set == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
if result == nil { if result == nil {
@@ -163,7 +163,7 @@ func execSInter(db *DB, args [][]byte) redis.Reply {
result = result.Intersect(set) result = result.Intersect(set)
if result.Len() == 0 { if result.Len() == 0 {
// early termination // early termination
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
} }
} }
@@ -175,7 +175,7 @@ func execSInter(db *DB, args [][]byte) redis.Reply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(arr) return protocol.MakeMultiBulkReply(arr)
} }
// execSInterStore intersects multiple sets and store the result in a key // execSInterStore intersects multiple sets and store the result in a key
@@ -195,7 +195,7 @@ func execSInterStore(db *DB, args [][]byte) redis.Reply {
} }
if set == nil { if set == nil {
db.Remove(dest) // clean ttl and old value db.Remove(dest) // clean ttl and old value
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
if result == nil { if result == nil {
@@ -206,7 +206,7 @@ func execSInterStore(db *DB, args [][]byte) redis.Reply {
if result.Len() == 0 { if result.Len() == 0 {
// early termination // early termination
db.Remove(dest) // clean ttl and old value db.Remove(dest) // clean ttl and old value
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
} }
} }
@@ -216,7 +216,7 @@ func execSInterStore(db *DB, args [][]byte) redis.Reply {
Data: set, Data: set,
}) })
db.addAof(utils.ToCmdLine3("sinterstore", args...)) db.addAof(utils.ToCmdLine3("sinterstore", args...))
return reply.MakeIntReply(int64(set.Len())) return protocol.MakeIntReply(int64(set.Len()))
} }
// execSUnion adds multiple sets // execSUnion adds multiple sets
@@ -246,7 +246,7 @@ func execSUnion(db *DB, args [][]byte) redis.Reply {
if result == nil { if result == nil {
// all keys are empty set // all keys are empty set
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
arr := make([][]byte, result.Len()) arr := make([][]byte, result.Len())
i := 0 i := 0
@@ -255,7 +255,7 @@ func execSUnion(db *DB, args [][]byte) redis.Reply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(arr) return protocol.MakeMultiBulkReply(arr)
} }
// execSUnionStore adds multiple sets and store the result in a key // execSUnionStore adds multiple sets and store the result in a key
@@ -287,7 +287,7 @@ func execSUnionStore(db *DB, args [][]byte) redis.Reply {
db.Remove(dest) // clean ttl db.Remove(dest) // clean ttl
if result == nil { if result == nil {
// all keys are empty set // all keys are empty set
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
set := HashSet.Make(result.ToSlice()...) set := HashSet.Make(result.ToSlice()...)
@@ -296,7 +296,7 @@ func execSUnionStore(db *DB, args [][]byte) redis.Reply {
}) })
db.addAof(utils.ToCmdLine3("sunionstore", args...)) db.addAof(utils.ToCmdLine3("sunionstore", args...))
return reply.MakeIntReply(int64(set.Len())) return protocol.MakeIntReply(int64(set.Len()))
} }
// execSDiff subtracts multiple sets // execSDiff subtracts multiple sets
@@ -315,7 +315,7 @@ func execSDiff(db *DB, args [][]byte) redis.Reply {
if set == nil { if set == nil {
if i == 0 { if i == 0 {
// early termination // early termination
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
continue continue
} }
@@ -326,14 +326,14 @@ func execSDiff(db *DB, args [][]byte) redis.Reply {
result = result.Diff(set) result = result.Diff(set)
if result.Len() == 0 { if result.Len() == 0 {
// early termination // early termination
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
} }
} }
if result == nil { if result == nil {
// all keys are nil // all keys are nil
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
arr := make([][]byte, result.Len()) arr := make([][]byte, result.Len())
i := 0 i := 0
@@ -342,7 +342,7 @@ func execSDiff(db *DB, args [][]byte) redis.Reply {
i++ i++
return true return true
}) })
return reply.MakeMultiBulkReply(arr) return protocol.MakeMultiBulkReply(arr)
} }
// execSDiffStore subtracts multiple sets and store the result in a key // execSDiffStore subtracts multiple sets and store the result in a key
@@ -364,7 +364,7 @@ func execSDiffStore(db *DB, args [][]byte) redis.Reply {
if i == 0 { if i == 0 {
// early termination // early termination
db.Remove(dest) db.Remove(dest)
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
continue continue
} }
@@ -376,7 +376,7 @@ func execSDiffStore(db *DB, args [][]byte) redis.Reply {
if result.Len() == 0 { if result.Len() == 0 {
// early termination // early termination
db.Remove(dest) db.Remove(dest)
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
} }
} }
@@ -384,7 +384,7 @@ func execSDiffStore(db *DB, args [][]byte) redis.Reply {
if result == nil { if result == nil {
// all keys are nil // all keys are nil
db.Remove(dest) db.Remove(dest)
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
set := HashSet.Make(result.ToSlice()...) set := HashSet.Make(result.ToSlice()...)
db.PutEntity(dest, &database.DataEntity{ db.PutEntity(dest, &database.DataEntity{
@@ -392,13 +392,13 @@ func execSDiffStore(db *DB, args [][]byte) redis.Reply {
}) })
db.addAof(utils.ToCmdLine3("sdiffstore", args...)) db.addAof(utils.ToCmdLine3("sdiffstore", args...))
return reply.MakeIntReply(int64(set.Len())) return protocol.MakeIntReply(int64(set.Len()))
} }
// execSRandMember gets random members from set // execSRandMember gets random members from set
func execSRandMember(db *DB, args [][]byte) redis.Reply { func execSRandMember(db *DB, args [][]byte) redis.Reply {
if len(args) != 1 && len(args) != 2 { if len(args) != 1 && len(args) != 2 {
return reply.MakeErrReply("ERR wrong number of arguments for 'srandmember' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'srandmember' command")
} }
key := string(args[0]) key := string(args[0])
@@ -408,16 +408,16 @@ func execSRandMember(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if set == nil { if set == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
if len(args) == 1 { if len(args) == 1 {
// get a random member // get a random member
members := set.RandomMembers(1) members := set.RandomMembers(1)
return reply.MakeBulkReply([]byte(members[0])) return protocol.MakeBulkReply([]byte(members[0]))
} }
count64, err := strconv.ParseInt(string(args[1]), 10, 64) count64, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
count := int(count64) count := int(count64)
if count > 0 { if count > 0 {
@@ -426,16 +426,16 @@ func execSRandMember(db *DB, args [][]byte) redis.Reply {
for i, v := range members { for i, v := range members {
result[i] = []byte(v) result[i] = []byte(v)
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} else if count < 0 { } else if count < 0 {
members := set.RandomMembers(-count) members := set.RandomMembers(-count)
result := make([][]byte, len(members)) result := make([][]byte, len(members))
for i, v := range members { for i, v := range members {
result[i] = []byte(v) result[i] = []byte(v)
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
func init() { func init() {

View File

@@ -3,8 +3,8 @@ package database
import ( import (
"fmt" "fmt"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"strconv" "strconv"
"testing" "testing"
) )
@@ -34,9 +34,9 @@ func TestSAdd(t *testing.T) {
// test members // test members
result = testDB.Exec(nil, utils.ToCmdLine("SMembers", key)) result = testDB.Exec(nil, utils.ToCmdLine("SMembers", key))
multiBulk, ok := result.(*reply.MultiBulkReply) multiBulk, ok := result.(*protocol.MultiBulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected bulk protocol, actually %s", result.ToBytes()))
return return
} }
if len(multiBulk.Args) != size { if len(multiBulk.Args) != size {
@@ -183,17 +183,17 @@ func TestSRandMember(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine("sadd", key, member)) testDB.Exec(nil, utils.ToCmdLine("sadd", key, member))
} }
result := testDB.Exec(nil, utils.ToCmdLine("SRandMember", key)) result := testDB.Exec(nil, utils.ToCmdLine("SRandMember", key))
br, ok := result.(*reply.BulkReply) br, ok := result.(*protocol.BulkReply)
if !ok && len(br.Arg) > 0 { if !ok && len(br.Arg) > 0 {
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected bulk protocol, actually %s", result.ToBytes()))
return return
} }
result = testDB.Exec(nil, utils.ToCmdLine("SRandMember", key, "10")) result = testDB.Exec(nil, utils.ToCmdLine("SRandMember", key, "10"))
asserts.AssertMultiBulkReplySize(t, result, 10) asserts.AssertMultiBulkReplySize(t, result, 10)
multiBulk, ok := result.(*reply.MultiBulkReply) multiBulk, ok := result.(*protocol.MultiBulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes())) t.Error(fmt.Sprintf("expected bulk protocol, actually %s", result.ToBytes()))
return return
} }
m := make(map[string]struct{}) m := make(map[string]struct{})

View File

@@ -5,24 +5,24 @@ import (
"github.com/hdt3213/godis/interface/database" "github.com/hdt3213/godis/interface/database"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
"strings" "strings"
) )
func (db *DB) getAsSortedSet(key string) (*SortedSet.SortedSet, reply.ErrorReply) { func (db *DB) getAsSortedSet(key string) (*SortedSet.SortedSet, protocol.ErrorReply) {
entity, exists := db.GetEntity(key) entity, exists := db.GetEntity(key)
if !exists { if !exists {
return nil, nil return nil, nil
} }
sortedSet, ok := entity.Data.(*SortedSet.SortedSet) sortedSet, ok := entity.Data.(*SortedSet.SortedSet)
if !ok { if !ok {
return nil, &reply.WrongTypeErrReply{} return nil, &protocol.WrongTypeErrReply{}
} }
return sortedSet, nil return sortedSet, nil
} }
func (db *DB) getOrInitSortedSet(key string) (sortedSet *SortedSet.SortedSet, inited bool, errReply reply.ErrorReply) { func (db *DB) getOrInitSortedSet(key string) (sortedSet *SortedSet.SortedSet, inited bool, errReply protocol.ErrorReply) {
sortedSet, errReply = db.getAsSortedSet(key) sortedSet, errReply = db.getAsSortedSet(key)
if errReply != nil { if errReply != nil {
return nil, false, errReply return nil, false, errReply
@@ -41,7 +41,7 @@ func (db *DB) getOrInitSortedSet(key string) (sortedSet *SortedSet.SortedSet, in
// execZAdd adds member into sorted set // execZAdd adds member into sorted set
func execZAdd(db *DB, args [][]byte) redis.Reply { func execZAdd(db *DB, args [][]byte) redis.Reply {
if len(args)%2 != 1 { if len(args)%2 != 1 {
return reply.MakeSyntaxErrReply() return protocol.MakeSyntaxErrReply()
} }
key := string(args[0]) key := string(args[0])
size := (len(args) - 1) / 2 size := (len(args) - 1) / 2
@@ -51,7 +51,7 @@ func execZAdd(db *DB, args [][]byte) redis.Reply {
member := string(args[2*i+2]) member := string(args[2*i+2])
score, err := strconv.ParseFloat(string(scoreValue), 64) score, err := strconv.ParseFloat(string(scoreValue), 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
elements[i] = &SortedSet.Element{ elements[i] = &SortedSet.Element{
Member: member, Member: member,
@@ -74,7 +74,7 @@ func execZAdd(db *DB, args [][]byte) redis.Reply {
db.addAof(utils.ToCmdLine3("zadd", args...)) db.addAof(utils.ToCmdLine3("zadd", args...))
return reply.MakeIntReply(int64(i)) return protocol.MakeIntReply(int64(i))
} }
func undoZAdd(db *DB, args [][]byte) []CmdLine { func undoZAdd(db *DB, args [][]byte) []CmdLine {
@@ -98,15 +98,15 @@ func execZScore(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
element, exists := sortedSet.Get(member) element, exists := sortedSet.Get(member)
if !exists { if !exists {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
value := strconv.FormatFloat(element.Score, 'f', -1, 64) value := strconv.FormatFloat(element.Score, 'f', -1, 64)
return reply.MakeBulkReply([]byte(value)) return protocol.MakeBulkReply([]byte(value))
} }
// execZRank gets index of a member in sortedset, ascending order, start from 0 // execZRank gets index of a member in sortedset, ascending order, start from 0
@@ -121,14 +121,14 @@ func execZRank(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
rank := sortedSet.GetRank(member, false) rank := sortedSet.GetRank(member, false)
if rank < 0 { if rank < 0 {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
return reply.MakeIntReply(rank) return protocol.MakeIntReply(rank)
} }
// execZRevRank gets index of a member in sortedset, descending order, start from 0 // execZRevRank gets index of a member in sortedset, descending order, start from 0
@@ -143,14 +143,14 @@ func execZRevRank(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
rank := sortedSet.GetRank(member, true) rank := sortedSet.GetRank(member, true)
if rank < 0 { if rank < 0 {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
return reply.MakeIntReply(rank) return protocol.MakeIntReply(rank)
} }
// execZCard gets number of members in sortedset // execZCard gets number of members in sortedset
@@ -164,33 +164,33 @@ func execZCard(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
return reply.MakeIntReply(sortedSet.Len()) return protocol.MakeIntReply(sortedSet.Len())
} }
// execZRange gets members in range, sort by score in ascending order // execZRange gets members in range, sort by score in ascending order
func execZRange(db *DB, args [][]byte) redis.Reply { func execZRange(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args) != 3 && len(args) != 4 { if len(args) != 3 && len(args) != 4 {
return reply.MakeErrReply("ERR wrong number of arguments for 'zrange' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'zrange' command")
} }
withScores := false withScores := false
if len(args) == 4 { if len(args) == 4 {
if strings.ToUpper(string(args[3])) != "WITHSCORES" { if strings.ToUpper(string(args[3])) != "WITHSCORES" {
return reply.MakeErrReply("syntax error") return protocol.MakeErrReply("syntax error")
} }
withScores = true withScores = true
} }
key := string(args[0]) key := string(args[0])
start, err := strconv.ParseInt(string(args[1]), 10, 64) start, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
stop, err := strconv.ParseInt(string(args[2]), 10, 64) stop, err := strconv.ParseInt(string(args[2]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
return range0(db, key, start, stop, withScores, false) return range0(db, key, start, stop, withScores, false)
} }
@@ -199,23 +199,23 @@ func execZRange(db *DB, args [][]byte) redis.Reply {
func execZRevRange(db *DB, args [][]byte) redis.Reply { func execZRevRange(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args) != 3 && len(args) != 4 { if len(args) != 3 && len(args) != 4 {
return reply.MakeErrReply("ERR wrong number of arguments for 'zrevrange' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'zrevrange' command")
} }
withScores := false withScores := false
if len(args) == 4 { if len(args) == 4 {
if string(args[3]) != "WITHSCORES" { if string(args[3]) != "WITHSCORES" {
return reply.MakeErrReply("syntax error") return protocol.MakeErrReply("syntax error")
} }
withScores = true withScores = true
} }
key := string(args[0]) key := string(args[0])
start, err := strconv.ParseInt(string(args[1]), 10, 64) start, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
stop, err := strconv.ParseInt(string(args[2]), 10, 64) stop, err := strconv.ParseInt(string(args[2]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
return range0(db, key, start, stop, withScores, true) return range0(db, key, start, stop, withScores, true)
} }
@@ -227,7 +227,7 @@ func range0(db *DB, key string, start int64, stop int64, withScores bool, desc b
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
// compute index // compute index
@@ -237,7 +237,7 @@ func range0(db *DB, key string, start int64, stop int64, withScores bool, desc b
} else if start < 0 { } else if start < 0 {
start = size + start start = size + start
} else if start >= size { } else if start >= size {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
if stop < -1*size { if stop < -1*size {
stop = 0 stop = 0
@@ -264,7 +264,7 @@ func range0(db *DB, key string, start int64, stop int64, withScores bool, desc b
result[i] = []byte(scoreStr) result[i] = []byte(scoreStr)
i++ i++
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
result := make([][]byte, len(slice)) result := make([][]byte, len(slice))
i := 0 i := 0
@@ -272,7 +272,7 @@ func range0(db *DB, key string, start int64, stop int64, withScores bool, desc b
result[i] = []byte(element.Member) result[i] = []byte(element.Member)
i++ i++
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
// execZCount gets number of members which score within given range // execZCount gets number of members which score within given range
@@ -281,12 +281,12 @@ func execZCount(db *DB, args [][]byte) redis.Reply {
min, err := SortedSet.ParseScoreBorder(string(args[1])) min, err := SortedSet.ParseScoreBorder(string(args[1]))
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
max, err := SortedSet.ParseScoreBorder(string(args[2])) max, err := SortedSet.ParseScoreBorder(string(args[2]))
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
// get data // get data
@@ -295,10 +295,10 @@ func execZCount(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
return reply.MakeIntReply(sortedSet.Count(min, max)) return protocol.MakeIntReply(sortedSet.Count(min, max))
} }
/* /*
@@ -311,7 +311,7 @@ func rangeByScore0(db *DB, key string, min *SortedSet.ScoreBorder, max *SortedSe
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
slice := sortedSet.RangeByScore(min, max, offset, limit, desc) slice := sortedSet.RangeByScore(min, max, offset, limit, desc)
@@ -325,7 +325,7 @@ func rangeByScore0(db *DB, key string, min *SortedSet.ScoreBorder, max *SortedSe
result[i] = []byte(scoreStr) result[i] = []byte(scoreStr)
i++ i++
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
result := make([][]byte, len(slice)) result := make([][]byte, len(slice))
i := 0 i := 0
@@ -333,24 +333,24 @@ func rangeByScore0(db *DB, key string, min *SortedSet.ScoreBorder, max *SortedSe
result[i] = []byte(element.Member) result[i] = []byte(element.Member)
i++ i++
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
// execZRangeByScore gets members which score within given range, in ascending order // execZRangeByScore gets members which score within given range, in ascending order
func execZRangeByScore(db *DB, args [][]byte) redis.Reply { func execZRangeByScore(db *DB, args [][]byte) redis.Reply {
if len(args) < 3 { if len(args) < 3 {
return reply.MakeErrReply("ERR wrong number of arguments for 'zrangebyscore' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'zrangebyscore' command")
} }
key := string(args[0]) key := string(args[0])
min, err := SortedSet.ParseScoreBorder(string(args[1])) min, err := SortedSet.ParseScoreBorder(string(args[1]))
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
max, err := SortedSet.ParseScoreBorder(string(args[2])) max, err := SortedSet.ParseScoreBorder(string(args[2]))
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
withScores := false withScores := false
@@ -364,19 +364,19 @@ func execZRangeByScore(db *DB, args [][]byte) redis.Reply {
i++ i++
} else if strings.ToUpper(s) == "LIMIT" { } else if strings.ToUpper(s) == "LIMIT" {
if len(args) < i+3 { if len(args) < i+3 {
return reply.MakeErrReply("ERR syntax error") return protocol.MakeErrReply("ERR syntax error")
} }
offset, err = strconv.ParseInt(string(args[i+1]), 10, 64) offset, err = strconv.ParseInt(string(args[i+1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
limit, err = strconv.ParseInt(string(args[i+2]), 10, 64) limit, err = strconv.ParseInt(string(args[i+2]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
i += 3 i += 3
} else { } else {
return reply.MakeErrReply("ERR syntax error") return protocol.MakeErrReply("ERR syntax error")
} }
} }
} }
@@ -386,18 +386,18 @@ func execZRangeByScore(db *DB, args [][]byte) redis.Reply {
// execZRevRangeByScore gets number of members which score within given range, in descending order // execZRevRangeByScore gets number of members which score within given range, in descending order
func execZRevRangeByScore(db *DB, args [][]byte) redis.Reply { func execZRevRangeByScore(db *DB, args [][]byte) redis.Reply {
if len(args) < 3 { if len(args) < 3 {
return reply.MakeErrReply("ERR wrong number of arguments for 'zrangebyscore' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'zrangebyscore' command")
} }
key := string(args[0]) key := string(args[0])
min, err := SortedSet.ParseScoreBorder(string(args[2])) min, err := SortedSet.ParseScoreBorder(string(args[2]))
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
max, err := SortedSet.ParseScoreBorder(string(args[1])) max, err := SortedSet.ParseScoreBorder(string(args[1]))
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
withScores := false withScores := false
@@ -411,19 +411,19 @@ func execZRevRangeByScore(db *DB, args [][]byte) redis.Reply {
i++ i++
} else if strings.ToUpper(s) == "LIMIT" { } else if strings.ToUpper(s) == "LIMIT" {
if len(args) < i+3 { if len(args) < i+3 {
return reply.MakeErrReply("ERR syntax error") return protocol.MakeErrReply("ERR syntax error")
} }
offset, err = strconv.ParseInt(string(args[i+1]), 10, 64) offset, err = strconv.ParseInt(string(args[i+1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
limit, err = strconv.ParseInt(string(args[i+2]), 10, 64) limit, err = strconv.ParseInt(string(args[i+2]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
i += 3 i += 3
} else { } else {
return reply.MakeErrReply("ERR syntax error") return protocol.MakeErrReply("ERR syntax error")
} }
} }
} }
@@ -433,18 +433,18 @@ func execZRevRangeByScore(db *DB, args [][]byte) redis.Reply {
// execZRemRangeByScore removes members which score within given range // execZRemRangeByScore removes members which score within given range
func execZRemRangeByScore(db *DB, args [][]byte) redis.Reply { func execZRemRangeByScore(db *DB, args [][]byte) redis.Reply {
if len(args) != 3 { if len(args) != 3 {
return reply.MakeErrReply("ERR wrong number of arguments for 'zremrangebyscore' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'zremrangebyscore' command")
} }
key := string(args[0]) key := string(args[0])
min, err := SortedSet.ParseScoreBorder(string(args[1])) min, err := SortedSet.ParseScoreBorder(string(args[1]))
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
max, err := SortedSet.ParseScoreBorder(string(args[2])) max, err := SortedSet.ParseScoreBorder(string(args[2]))
if err != nil { if err != nil {
return reply.MakeErrReply(err.Error()) return protocol.MakeErrReply(err.Error())
} }
// get data // get data
@@ -453,14 +453,14 @@ func execZRemRangeByScore(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return &reply.EmptyMultiBulkReply{} return &protocol.EmptyMultiBulkReply{}
} }
removed := sortedSet.RemoveByScore(min, max) removed := sortedSet.RemoveByScore(min, max)
if removed > 0 { if removed > 0 {
db.addAof(utils.ToCmdLine3("zremrangebyscore", args...)) db.addAof(utils.ToCmdLine3("zremrangebyscore", args...))
} }
return reply.MakeIntReply(removed) return protocol.MakeIntReply(removed)
} }
// execZRemRangeByRank removes members within given indexes // execZRemRangeByRank removes members within given indexes
@@ -468,11 +468,11 @@ func execZRemRangeByRank(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
start, err := strconv.ParseInt(string(args[1]), 10, 64) start, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
stop, err := strconv.ParseInt(string(args[2]), 10, 64) stop, err := strconv.ParseInt(string(args[2]), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
// get data // get data
@@ -481,7 +481,7 @@ func execZRemRangeByRank(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
// compute index // compute index
@@ -491,7 +491,7 @@ func execZRemRangeByRank(db *DB, args [][]byte) redis.Reply {
} else if start < 0 { } else if start < 0 {
start = size + start start = size + start
} else if start >= size { } else if start >= size {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
if stop < -1*size { if stop < -1*size {
stop = 0 stop = 0
@@ -511,7 +511,7 @@ func execZRemRangeByRank(db *DB, args [][]byte) redis.Reply {
if removed > 0 { if removed > 0 {
db.addAof(utils.ToCmdLine3("zremrangebyrank", args...)) db.addAof(utils.ToCmdLine3("zremrangebyrank", args...))
} }
return reply.MakeIntReply(removed) return protocol.MakeIntReply(removed)
} }
// execZRem removes given members // execZRem removes given members
@@ -530,7 +530,7 @@ func execZRem(db *DB, args [][]byte) redis.Reply {
return errReply return errReply
} }
if sortedSet == nil { if sortedSet == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
var deleted int64 = 0 var deleted int64 = 0
@@ -542,7 +542,7 @@ func execZRem(db *DB, args [][]byte) redis.Reply {
if deleted > 0 { if deleted > 0 {
db.addAof(utils.ToCmdLine3("zrem", args...)) db.addAof(utils.ToCmdLine3("zrem", args...))
} }
return reply.MakeIntReply(deleted) return protocol.MakeIntReply(deleted)
} }
func undoZRem(db *DB, args [][]byte) []CmdLine { func undoZRem(db *DB, args [][]byte) []CmdLine {
@@ -562,7 +562,7 @@ func execZIncrBy(db *DB, args [][]byte) redis.Reply {
field := string(args[2]) field := string(args[2])
delta, err := strconv.ParseFloat(rawDelta, 64) delta, err := strconv.ParseFloat(rawDelta, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
// get or init entity // get or init entity
@@ -575,13 +575,13 @@ func execZIncrBy(db *DB, args [][]byte) redis.Reply {
if !exists { if !exists {
sortedSet.Add(field, delta) sortedSet.Add(field, delta)
db.addAof(utils.ToCmdLine3("zincrby", args...)) db.addAof(utils.ToCmdLine3("zincrby", args...))
return reply.MakeBulkReply(args[1]) return protocol.MakeBulkReply(args[1])
} }
score := element.Score + delta score := element.Score + delta
sortedSet.Add(field, score) sortedSet.Add(field, score)
bytes := []byte(strconv.FormatFloat(score, 'f', -1, 64)) bytes := []byte(strconv.FormatFloat(score, 'f', -1, 64))
db.addAof(utils.ToCmdLine3("zincrby", args...)) db.addAof(utils.ToCmdLine3("zincrby", args...))
return reply.MakeBulkReply(bytes) return protocol.MakeBulkReply(bytes)
} }
func undoZIncr(db *DB, args [][]byte) []CmdLine { func undoZIncr(db *DB, args [][]byte) []CmdLine {

View File

@@ -2,7 +2,7 @@ package database
import ( import (
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"math/rand" "math/rand"
"strconv" "strconv"
"testing" "testing"

View File

@@ -5,21 +5,21 @@ import (
"github.com/hdt3213/godis/interface/database" "github.com/hdt3213/godis/interface/database"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"strconv" "strconv"
"strings" "strings"
"time" "time"
) )
func (db *DB) getAsString(key string) ([]byte, reply.ErrorReply) { func (db *DB) getAsString(key string) ([]byte, protocol.ErrorReply) {
entity, ok := db.GetEntity(key) entity, ok := db.GetEntity(key)
if !ok { if !ok {
return nil, nil return nil, nil
} }
bytes, ok := entity.Data.([]byte) bytes, ok := entity.Data.([]byte)
if !ok { if !ok {
return nil, &reply.WrongTypeErrReply{} return nil, &protocol.WrongTypeErrReply{}
} }
return bytes, nil return bytes, nil
} }
@@ -32,9 +32,9 @@ func execGet(db *DB, args [][]byte) redis.Reply {
return err return err
} }
if bytes == nil { if bytes == nil {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
return reply.MakeBulkReply(bytes) return protocol.MakeBulkReply(bytes)
} }
const ( const (
@@ -58,49 +58,49 @@ func execSet(db *DB, args [][]byte) redis.Reply {
arg := strings.ToUpper(string(args[i])) arg := strings.ToUpper(string(args[i]))
if arg == "NX" { // insert if arg == "NX" { // insert
if policy == updatePolicy { if policy == updatePolicy {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
policy = insertPolicy policy = insertPolicy
} else if arg == "XX" { // update policy } else if arg == "XX" { // update policy
if policy == insertPolicy { if policy == insertPolicy {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
policy = updatePolicy policy = updatePolicy
} else if arg == "EX" { // ttl in seconds } else if arg == "EX" { // ttl in seconds
if ttl != unlimitedTTL { if ttl != unlimitedTTL {
// ttl has been set // ttl has been set
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
if i+1 >= len(args) { if i+1 >= len(args) {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
ttlArg, err := strconv.ParseInt(string(args[i+1]), 10, 64) ttlArg, err := strconv.ParseInt(string(args[i+1]), 10, 64)
if err != nil { if err != nil {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
if ttlArg <= 0 { if ttlArg <= 0 {
return reply.MakeErrReply("ERR invalid expire time in set") return protocol.MakeErrReply("ERR invalid expire time in set")
} }
ttl = ttlArg * 1000 ttl = ttlArg * 1000
i++ // skip next arg i++ // skip next arg
} else if arg == "PX" { // ttl in milliseconds } else if arg == "PX" { // ttl in milliseconds
if ttl != unlimitedTTL { if ttl != unlimitedTTL {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
if i+1 >= len(args) { if i+1 >= len(args) {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
ttlArg, err := strconv.ParseInt(string(args[i+1]), 10, 64) ttlArg, err := strconv.ParseInt(string(args[i+1]), 10, 64)
if err != nil { if err != nil {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
if ttlArg <= 0 { if ttlArg <= 0 {
return reply.MakeErrReply("ERR invalid expire time in set") return protocol.MakeErrReply("ERR invalid expire time in set")
} }
ttl = ttlArg ttl = ttlArg
i++ // skip next arg i++ // skip next arg
} else { } else {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
} }
} }
@@ -136,9 +136,9 @@ func execSet(db *DB, args [][]byte) redis.Reply {
} }
if result > 0 { if result > 0 {
return &reply.OkReply{} return &protocol.OkReply{}
} }
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
// execSetNX sets string if not exists // execSetNX sets string if not exists
@@ -150,7 +150,7 @@ func execSetNX(db *DB, args [][]byte) redis.Reply {
} }
result := db.PutIfAbsent(key, entity) result := db.PutIfAbsent(key, entity)
db.addAof(utils.ToCmdLine3("setnx", args...)) db.addAof(utils.ToCmdLine3("setnx", args...))
return reply.MakeIntReply(int64(result)) return protocol.MakeIntReply(int64(result))
} }
// execSetEX sets string and its ttl // execSetEX sets string and its ttl
@@ -160,10 +160,10 @@ func execSetEX(db *DB, args [][]byte) redis.Reply {
ttlArg, err := strconv.ParseInt(string(args[1]), 10, 64) ttlArg, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
if ttlArg <= 0 { if ttlArg <= 0 {
return reply.MakeErrReply("ERR invalid expire time in setex") return protocol.MakeErrReply("ERR invalid expire time in setex")
} }
ttl := ttlArg * 1000 ttl := ttlArg * 1000
@@ -176,7 +176,7 @@ func execSetEX(db *DB, args [][]byte) redis.Reply {
db.Expire(key, expireTime) db.Expire(key, expireTime)
db.addAof(utils.ToCmdLine3("setex", args...)) db.addAof(utils.ToCmdLine3("setex", args...))
db.addAof(aof.MakeExpireCmd(key, expireTime).Args) db.addAof(aof.MakeExpireCmd(key, expireTime).Args)
return &reply.OkReply{} return &protocol.OkReply{}
} }
// execPSetEX set a key's time to live in milliseconds // execPSetEX set a key's time to live in milliseconds
@@ -186,10 +186,10 @@ func execPSetEX(db *DB, args [][]byte) redis.Reply {
ttlArg, err := strconv.ParseInt(string(args[1]), 10, 64) ttlArg, err := strconv.ParseInt(string(args[1]), 10, 64)
if err != nil { if err != nil {
return &reply.SyntaxErrReply{} return &protocol.SyntaxErrReply{}
} }
if ttlArg <= 0 { if ttlArg <= 0 {
return reply.MakeErrReply("ERR invalid expire time in setex") return protocol.MakeErrReply("ERR invalid expire time in setex")
} }
entity := &database.DataEntity{ entity := &database.DataEntity{
@@ -202,7 +202,7 @@ func execPSetEX(db *DB, args [][]byte) redis.Reply {
db.addAof(utils.ToCmdLine3("setex", args...)) db.addAof(utils.ToCmdLine3("setex", args...))
db.addAof(aof.MakeExpireCmd(key, expireTime).Args) db.addAof(aof.MakeExpireCmd(key, expireTime).Args)
return &reply.OkReply{} return &protocol.OkReply{}
} }
func prepareMSet(args [][]byte) ([]string, []string) { func prepareMSet(args [][]byte) ([]string, []string) {
@@ -222,7 +222,7 @@ func undoMSet(db *DB, args [][]byte) []CmdLine {
// execMSet sets multi key-value in database // execMSet sets multi key-value in database
func execMSet(db *DB, args [][]byte) redis.Reply { func execMSet(db *DB, args [][]byte) redis.Reply {
if len(args)%2 != 0 { if len(args)%2 != 0 {
return reply.MakeSyntaxErrReply() return protocol.MakeSyntaxErrReply()
} }
size := len(args) / 2 size := len(args) / 2
@@ -238,7 +238,7 @@ func execMSet(db *DB, args [][]byte) redis.Reply {
db.PutEntity(key, &database.DataEntity{Data: value}) db.PutEntity(key, &database.DataEntity{Data: value})
} }
db.addAof(utils.ToCmdLine3("mset", args...)) db.addAof(utils.ToCmdLine3("mset", args...))
return &reply.OkReply{} return &protocol.OkReply{}
} }
func prepareMGet(args [][]byte) ([]string, []string) { func prepareMGet(args [][]byte) ([]string, []string) {
@@ -260,7 +260,7 @@ func execMGet(db *DB, args [][]byte) redis.Reply {
for i, key := range keys { for i, key := range keys {
bytes, err := db.getAsString(key) bytes, err := db.getAsString(key)
if err != nil { if err != nil {
_, isWrongType := err.(*reply.WrongTypeErrReply) _, isWrongType := err.(*protocol.WrongTypeErrReply)
if isWrongType { if isWrongType {
result[i] = nil result[i] = nil
continue continue
@@ -271,14 +271,14 @@ func execMGet(db *DB, args [][]byte) redis.Reply {
result[i] = bytes // nil or []byte result[i] = bytes // nil or []byte
} }
return reply.MakeMultiBulkReply(result) return protocol.MakeMultiBulkReply(result)
} }
// execMSetNX sets multi key-value in database, only if none of the given keys exist // execMSetNX sets multi key-value in database, only if none of the given keys exist
func execMSetNX(db *DB, args [][]byte) redis.Reply { func execMSetNX(db *DB, args [][]byte) redis.Reply {
// parse args // parse args
if len(args)%2 != 0 { if len(args)%2 != 0 {
return reply.MakeSyntaxErrReply() return protocol.MakeSyntaxErrReply()
} }
size := len(args) / 2 size := len(args) / 2
values := make([][]byte, size) values := make([][]byte, size)
@@ -291,7 +291,7 @@ func execMSetNX(db *DB, args [][]byte) redis.Reply {
for _, key := range keys { for _, key := range keys {
_, exists := db.GetEntity(key) _, exists := db.GetEntity(key)
if exists { if exists {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
} }
@@ -300,7 +300,7 @@ func execMSetNX(db *DB, args [][]byte) redis.Reply {
db.PutEntity(key, &database.DataEntity{Data: value}) db.PutEntity(key, &database.DataEntity{Data: value})
} }
db.addAof(utils.ToCmdLine3("msetnx", args...)) db.addAof(utils.ToCmdLine3("msetnx", args...))
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execGetSet sets value of a string-type key and returns its old value // execGetSet sets value of a string-type key and returns its old value
@@ -317,9 +317,9 @@ func execGetSet(db *DB, args [][]byte) redis.Reply {
db.Persist(key) // override ttl db.Persist(key) // override ttl
db.addAof(utils.ToCmdLine3("getset", args...)) db.addAof(utils.ToCmdLine3("getset", args...))
if old == nil { if old == nil {
return new(reply.NullBulkReply) return new(protocol.NullBulkReply)
} }
return reply.MakeBulkReply(old) return protocol.MakeBulkReply(old)
} }
// execIncr increments the integer value of a key by one // execIncr increments the integer value of a key by one
@@ -333,19 +333,19 @@ func execIncr(db *DB, args [][]byte) redis.Reply {
if bytes != nil { if bytes != nil {
val, err := strconv.ParseInt(string(bytes), 10, 64) val, err := strconv.ParseInt(string(bytes), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: []byte(strconv.FormatInt(val+1, 10)), Data: []byte(strconv.FormatInt(val+1, 10)),
}) })
db.addAof(utils.ToCmdLine3("incr", args...)) db.addAof(utils.ToCmdLine3("incr", args...))
return reply.MakeIntReply(val + 1) return protocol.MakeIntReply(val + 1)
} }
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: []byte("1"), Data: []byte("1"),
}) })
db.addAof(utils.ToCmdLine3("incr", args...)) db.addAof(utils.ToCmdLine3("incr", args...))
return reply.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execIncrBy increments the integer value of a key by given value // execIncrBy increments the integer value of a key by given value
@@ -354,7 +354,7 @@ func execIncrBy(db *DB, args [][]byte) redis.Reply {
rawDelta := string(args[1]) rawDelta := string(args[1])
delta, err := strconv.ParseInt(rawDelta, 10, 64) delta, err := strconv.ParseInt(rawDelta, 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
bytes, errReply := db.getAsString(key) bytes, errReply := db.getAsString(key)
@@ -365,19 +365,19 @@ func execIncrBy(db *DB, args [][]byte) redis.Reply {
// existed value // existed value
val, err := strconv.ParseInt(string(bytes), 10, 64) val, err := strconv.ParseInt(string(bytes), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: []byte(strconv.FormatInt(val+delta, 10)), Data: []byte(strconv.FormatInt(val+delta, 10)),
}) })
db.addAof(utils.ToCmdLine3("incrby", args...)) db.addAof(utils.ToCmdLine3("incrby", args...))
return reply.MakeIntReply(val + delta) return protocol.MakeIntReply(val + delta)
} }
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: args[1], Data: args[1],
}) })
db.addAof(utils.ToCmdLine3("incrby", args...)) db.addAof(utils.ToCmdLine3("incrby", args...))
return reply.MakeIntReply(delta) return protocol.MakeIntReply(delta)
} }
// execIncrByFloat increments the float value of a key by given value // execIncrByFloat increments the float value of a key by given value
@@ -386,7 +386,7 @@ func execIncrByFloat(db *DB, args [][]byte) redis.Reply {
rawDelta := string(args[1]) rawDelta := string(args[1])
delta, err := decimal.NewFromString(rawDelta) delta, err := decimal.NewFromString(rawDelta)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
bytes, errReply := db.getAsString(key) bytes, errReply := db.getAsString(key)
@@ -396,20 +396,20 @@ func execIncrByFloat(db *DB, args [][]byte) redis.Reply {
if bytes != nil { if bytes != nil {
val, err := decimal.NewFromString(string(bytes)) val, err := decimal.NewFromString(string(bytes))
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not a valid float") return protocol.MakeErrReply("ERR value is not a valid float")
} }
resultBytes := []byte(val.Add(delta).String()) resultBytes := []byte(val.Add(delta).String())
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: resultBytes, Data: resultBytes,
}) })
db.addAof(utils.ToCmdLine3("incrbyfloat", args...)) db.addAof(utils.ToCmdLine3("incrbyfloat", args...))
return reply.MakeBulkReply(resultBytes) return protocol.MakeBulkReply(resultBytes)
} }
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: args[1], Data: args[1],
}) })
db.addAof(utils.ToCmdLine3("incrbyfloat", args...)) db.addAof(utils.ToCmdLine3("incrbyfloat", args...))
return reply.MakeBulkReply(args[1]) return protocol.MakeBulkReply(args[1])
} }
// execDecr decrements the integer value of a key by one // execDecr decrements the integer value of a key by one
@@ -423,20 +423,20 @@ func execDecr(db *DB, args [][]byte) redis.Reply {
if bytes != nil { if bytes != nil {
val, err := strconv.ParseInt(string(bytes), 10, 64) val, err := strconv.ParseInt(string(bytes), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: []byte(strconv.FormatInt(val-1, 10)), Data: []byte(strconv.FormatInt(val-1, 10)),
}) })
db.addAof(utils.ToCmdLine3("decr", args...)) db.addAof(utils.ToCmdLine3("decr", args...))
return reply.MakeIntReply(val - 1) return protocol.MakeIntReply(val - 1)
} }
entity := &database.DataEntity{ entity := &database.DataEntity{
Data: []byte("-1"), Data: []byte("-1"),
} }
db.PutEntity(key, entity) db.PutEntity(key, entity)
db.addAof(utils.ToCmdLine3("decr", args...)) db.addAof(utils.ToCmdLine3("decr", args...))
return reply.MakeIntReply(-1) return protocol.MakeIntReply(-1)
} }
// execDecrBy decrements the integer value of a key by onedecrement // execDecrBy decrements the integer value of a key by onedecrement
@@ -445,7 +445,7 @@ func execDecrBy(db *DB, args [][]byte) redis.Reply {
rawDelta := string(args[1]) rawDelta := string(args[1])
delta, err := strconv.ParseInt(rawDelta, 10, 64) delta, err := strconv.ParseInt(rawDelta, 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
bytes, errReply := db.getAsString(key) bytes, errReply := db.getAsString(key)
@@ -455,20 +455,20 @@ func execDecrBy(db *DB, args [][]byte) redis.Reply {
if bytes != nil { if bytes != nil {
val, err := strconv.ParseInt(string(bytes), 10, 64) val, err := strconv.ParseInt(string(bytes), 10, 64)
if err != nil { if err != nil {
return reply.MakeErrReply("ERR value is not an integer or out of range") return protocol.MakeErrReply("ERR value is not an integer or out of range")
} }
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: []byte(strconv.FormatInt(val-delta, 10)), Data: []byte(strconv.FormatInt(val-delta, 10)),
}) })
db.addAof(utils.ToCmdLine3("decrby", args...)) db.addAof(utils.ToCmdLine3("decrby", args...))
return reply.MakeIntReply(val - delta) return protocol.MakeIntReply(val - delta)
} }
valueStr := strconv.FormatInt(-delta, 10) valueStr := strconv.FormatInt(-delta, 10)
db.PutEntity(key, &database.DataEntity{ db.PutEntity(key, &database.DataEntity{
Data: []byte(valueStr), Data: []byte(valueStr),
}) })
db.addAof(utils.ToCmdLine3("decrby", args...)) db.addAof(utils.ToCmdLine3("decrby", args...))
return reply.MakeIntReply(-delta) return protocol.MakeIntReply(-delta)
} }
// execStrLen returns len of string value bound to the given key // execStrLen returns len of string value bound to the given key
@@ -479,9 +479,9 @@ func execStrLen(db *DB, args [][]byte) redis.Reply {
return err return err
} }
if bytes == nil { if bytes == nil {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
return reply.MakeIntReply(int64(len(bytes))) return protocol.MakeIntReply(int64(len(bytes)))
} }
// execAppend sets string value to the given key // execAppend sets string value to the given key
@@ -496,7 +496,7 @@ func execAppend(db *DB, args [][]byte) redis.Reply {
Data: bytes, Data: bytes,
}) })
db.addAof(utils.ToCmdLine3("append", args...)) db.addAof(utils.ToCmdLine3("append", args...))
return reply.MakeIntReply(int64(len(bytes))) return protocol.MakeIntReply(int64(len(bytes)))
} }
// execSetRange overwrites part of the string stored at key, starting at the specified offset. // execSetRange overwrites part of the string stored at key, starting at the specified offset.
@@ -505,7 +505,7 @@ func execSetRange(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
offset, errNative := strconv.ParseInt(string(args[1]), 10, 64) offset, errNative := strconv.ParseInt(string(args[1]), 10, 64)
if errNative != nil { if errNative != nil {
return reply.MakeErrReply(errNative.Error()) return protocol.MakeErrReply(errNative.Error())
} }
value := args[2] value := args[2]
bytes, err := db.getAsString(key) bytes, err := db.getAsString(key)
@@ -531,18 +531,18 @@ func execSetRange(db *DB, args [][]byte) redis.Reply {
Data: bytes, Data: bytes,
}) })
db.addAof(utils.ToCmdLine3("setRange", args...)) db.addAof(utils.ToCmdLine3("setRange", args...))
return reply.MakeIntReply(int64(len(bytes))) return protocol.MakeIntReply(int64(len(bytes)))
} }
func execGetRange(db *DB, args [][]byte) redis.Reply { func execGetRange(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
startIdx, errNative := strconv.ParseInt(string(args[1]), 10, 64) startIdx, errNative := strconv.ParseInt(string(args[1]), 10, 64)
if errNative != nil { if errNative != nil {
return reply.MakeErrReply(errNative.Error()) return protocol.MakeErrReply(errNative.Error())
} }
endIdx, errNative := strconv.ParseInt(string(args[2]), 10, 64) endIdx, errNative := strconv.ParseInt(string(args[2]), 10, 64)
if errNative != nil { if errNative != nil {
return reply.MakeErrReply(errNative.Error()) return protocol.MakeErrReply(errNative.Error())
} }
bytes, err := db.getAsString(key) bytes, err := db.getAsString(key)
@@ -551,19 +551,19 @@ func execGetRange(db *DB, args [][]byte) redis.Reply {
} }
if bytes == nil { if bytes == nil {
return reply.MakeNullBulkReply() return protocol.MakeNullBulkReply()
} }
bytesLen := int64(len(bytes)) bytesLen := int64(len(bytes))
if startIdx < -1*bytesLen { if startIdx < -1*bytesLen {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} else if startIdx < 0 { } else if startIdx < 0 {
startIdx = bytesLen + startIdx startIdx = bytesLen + startIdx
} else if startIdx >= bytesLen { } else if startIdx >= bytesLen {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} }
if endIdx < -1*bytesLen { if endIdx < -1*bytesLen {
return &reply.NullBulkReply{} return &protocol.NullBulkReply{}
} else if endIdx < 0 { } else if endIdx < 0 {
endIdx = bytesLen + endIdx + 1 endIdx = bytesLen + endIdx + 1
} else if endIdx < bytesLen { } else if endIdx < bytesLen {
@@ -572,10 +572,10 @@ func execGetRange(db *DB, args [][]byte) redis.Reply {
endIdx = bytesLen endIdx = bytesLen
} }
if startIdx > endIdx { if startIdx > endIdx {
return reply.MakeNullBulkReply() return protocol.MakeNullBulkReply()
} }
return reply.MakeBulkReply(bytes[startIdx:endIdx]) return protocol.MakeBulkReply(bytes[startIdx:endIdx])
} }
func init() { func init() {

View File

@@ -3,8 +3,8 @@ package database
import ( import (
"fmt" "fmt"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"strconv" "strconv"
"testing" "testing"
) )
@@ -18,7 +18,7 @@ func TestSet2(t *testing.T) {
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
testDB.Exec(nil, utils.ToCmdLine("SET", key, value)) testDB.Exec(nil, utils.ToCmdLine("SET", key, value))
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected := reply.MakeBulkReply([]byte(value)) expected := protocol.MakeBulkReply([]byte(value))
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
@@ -33,14 +33,14 @@ func TestSet(t *testing.T) {
// normal set // normal set
testDB.Exec(nil, utils.ToCmdLine("SET", key, value)) testDB.Exec(nil, utils.ToCmdLine("SET", key, value))
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected := reply.MakeBulkReply([]byte(value)) expected := protocol.MakeBulkReply([]byte(value))
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
// set nx // set nx
actual = testDB.Exec(nil, utils.ToCmdLine("SET", key, value, "NX")) actual = testDB.Exec(nil, utils.ToCmdLine("SET", key, value, "NX"))
if _, ok := actual.(*reply.NullBulkReply); !ok { if _, ok := actual.(*protocol.NullBulkReply); !ok {
t.Error("expected true actual false") t.Error("expected true actual false")
} }
@@ -49,7 +49,7 @@ func TestSet(t *testing.T) {
value = utils.RandString(10) value = utils.RandString(10)
actual = testDB.Exec(nil, utils.ToCmdLine("SET", key, value, "NX")) actual = testDB.Exec(nil, utils.ToCmdLine("SET", key, value, "NX"))
actual = testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual = testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected = reply.MakeBulkReply([]byte(value)) expected = protocol.MakeBulkReply([]byte(value))
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
@@ -59,7 +59,7 @@ func TestSet(t *testing.T) {
key = utils.RandString(10) key = utils.RandString(10)
value = utils.RandString(10) value = utils.RandString(10)
actual = testDB.Exec(nil, utils.ToCmdLine("SET", key, value, "XX")) actual = testDB.Exec(nil, utils.ToCmdLine("SET", key, value, "XX"))
if _, ok := actual.(*reply.NullBulkReply); !ok { if _, ok := actual.(*protocol.NullBulkReply); !ok {
t.Error("expected true actually false ") t.Error("expected true actually false ")
} }
@@ -77,9 +77,9 @@ func TestSet(t *testing.T) {
asserts.AssertBulkReply(t, actual, value) asserts.AssertBulkReply(t, actual, value)
actual = execTTL(testDB, utils.ToCmdLine(key)) actual = execTTL(testDB, utils.ToCmdLine(key))
actual = testDB.Exec(nil, utils.ToCmdLine("TTL", key)) actual = testDB.Exec(nil, utils.ToCmdLine("TTL", key))
intResult, ok := actual.(*reply.IntReply) intResult, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", actual.ToBytes()))
return return
} }
if intResult.Code <= 0 || intResult.Code > 1000 { if intResult.Code <= 0 || intResult.Code > 1000 {
@@ -94,9 +94,9 @@ func TestSet(t *testing.T) {
actual = testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual = testDB.Exec(nil, utils.ToCmdLine("GET", key))
asserts.AssertBulkReply(t, actual, value) asserts.AssertBulkReply(t, actual, value)
actual = testDB.Exec(nil, utils.ToCmdLine("TTL", key)) actual = testDB.Exec(nil, utils.ToCmdLine("TTL", key))
intResult, ok = actual.(*reply.IntReply) intResult, ok = actual.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", actual.ToBytes()))
return return
} }
if intResult.Code <= 0 || intResult.Code > 1000 { if intResult.Code <= 0 || intResult.Code > 1000 {
@@ -111,13 +111,13 @@ func TestSetNX(t *testing.T) {
value := utils.RandString(10) value := utils.RandString(10)
testDB.Exec(nil, utils.ToCmdLine("SETNX", key, value)) testDB.Exec(nil, utils.ToCmdLine("SETNX", key, value))
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected := reply.MakeBulkReply([]byte(value)) expected := protocol.MakeBulkReply([]byte(value))
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
actual = testDB.Exec(nil, utils.ToCmdLine("SETNX", key, value)) actual = testDB.Exec(nil, utils.ToCmdLine("SETNX", key, value))
expected2 := reply.MakeIntReply(int64(0)) expected2 := protocol.MakeIntReply(int64(0))
if !utils.BytesEquals(actual.ToBytes(), expected2.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected2.ToBytes()) {
t.Error("expected: " + string(expected2.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected2.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
@@ -133,9 +133,9 @@ func TestSetEX(t *testing.T) {
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
asserts.AssertBulkReply(t, actual, value) asserts.AssertBulkReply(t, actual, value)
actual = testDB.Exec(nil, utils.ToCmdLine("TTL", key)) actual = testDB.Exec(nil, utils.ToCmdLine("TTL", key))
intResult, ok := actual.(*reply.IntReply) intResult, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", actual.ToBytes()))
return return
} }
if intResult.Code <= 0 || intResult.Code > 1000 { if intResult.Code <= 0 || intResult.Code > 1000 {
@@ -154,9 +154,9 @@ func TestPSetEX(t *testing.T) {
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
asserts.AssertBulkReply(t, actual, value) asserts.AssertBulkReply(t, actual, value)
actual = testDB.Exec(nil, utils.ToCmdLine("PTTL", key)) actual = testDB.Exec(nil, utils.ToCmdLine("PTTL", key))
intResult, ok := actual.(*reply.IntReply) intResult, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes())) t.Error(fmt.Sprintf("expected int protocol, actually %s", actual.ToBytes()))
return return
} }
if intResult.Code <= 0 || intResult.Code > 1000000 { if intResult.Code <= 0 || intResult.Code > 1000000 {
@@ -179,7 +179,7 @@ func TestMSet(t *testing.T) {
} }
testDB.Exec(nil, utils.ToCmdLine2("MSET", args...)) testDB.Exec(nil, utils.ToCmdLine2("MSET", args...))
actual := testDB.Exec(nil, utils.ToCmdLine2("MGET", keys...)) actual := testDB.Exec(nil, utils.ToCmdLine2("MGET", keys...))
expected := reply.MakeMultiBulkReply(values) expected := protocol.MakeMultiBulkReply(values)
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
@@ -190,7 +190,7 @@ func TestMSet(t *testing.T) {
key2 := utils.RandString(10) key2 := utils.RandString(10)
testDB.Exec(nil, utils.ToCmdLine2("LPush", key2, key2)) testDB.Exec(nil, utils.ToCmdLine2("LPush", key2, key2))
actual = testDB.Exec(nil, utils.ToCmdLine2("MGET", key1, key2)) actual = testDB.Exec(nil, utils.ToCmdLine2("MGET", key1, key2))
arr := actual.(*reply.MultiBulkReply) arr := actual.(*protocol.MultiBulkReply)
if string(arr.Args[0]) != key1 { if string(arr.Args[0]) != key1 {
t.Error("expected: " + key1 + ", actual: " + string(arr.Args[1])) t.Error("expected: " + key1 + ", actual: " + string(arr.Args[1]))
} }
@@ -206,7 +206,7 @@ func TestIncr(t *testing.T) {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
testDB.Exec(nil, utils.ToCmdLine("INCR", key)) testDB.Exec(nil, utils.ToCmdLine("INCR", key))
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(i+1), 10))) expected := protocol.MakeBulkReply([]byte(strconv.FormatInt(int64(i+1), 10)))
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
@@ -214,7 +214,7 @@ func TestIncr(t *testing.T) {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
testDB.Exec(nil, utils.ToCmdLine("INCRBY", key, "-1")) testDB.Exec(nil, utils.ToCmdLine("INCRBY", key, "-1"))
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(size-i-1), 10))) expected := protocol.MakeBulkReply([]byte(strconv.FormatInt(int64(size-i-1), 10)))
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
@@ -225,7 +225,7 @@ func TestIncr(t *testing.T) {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
testDB.Exec(nil, utils.ToCmdLine("INCRBY", key, "1")) testDB.Exec(nil, utils.ToCmdLine("INCRBY", key, "1"))
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(i+1), 10))) expected := protocol.MakeBulkReply([]byte(strconv.FormatInt(int64(i+1), 10)))
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) { if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes())) t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
} }
@@ -235,9 +235,9 @@ func TestIncr(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine("INCRBYFLOAT", key, "-1.0")) testDB.Exec(nil, utils.ToCmdLine("INCRBYFLOAT", key, "-1.0"))
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected := -i - 1 expected := -i - 1
bulk, ok := actual.(*reply.BulkReply) bulk, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected bulk reply, actually %s", actual.ToBytes())) t.Error(fmt.Sprintf("expected bulk protocol, actually %s", actual.ToBytes()))
return return
} }
val, err := strconv.ParseFloat(string(bulk.Arg), 10) val, err := strconv.ParseFloat(string(bulk.Arg), 10)
@@ -266,9 +266,9 @@ func TestDecr(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine("DECRBY", key, "1")) testDB.Exec(nil, utils.ToCmdLine("DECRBY", key, "1"))
actual := testDB.Exec(nil, utils.ToCmdLine("GET", key)) actual := testDB.Exec(nil, utils.ToCmdLine("GET", key))
expected := -i - 1 expected := -i - 1
bulk, ok := actual.(*reply.BulkReply) bulk, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Error(fmt.Sprintf("expected bulk reply, actually %s", actual.ToBytes())) t.Error(fmt.Sprintf("expected bulk protocol, actually %s", actual.ToBytes()))
return return
} }
val, err := strconv.ParseFloat(string(bulk.Arg), 10) val, err := strconv.ParseFloat(string(bulk.Arg), 10)
@@ -289,9 +289,9 @@ func TestGetSet(t *testing.T) {
value := utils.RandString(10) value := utils.RandString(10)
actual := testDB.Exec(nil, utils.ToCmdLine("GETSET", key, value)) actual := testDB.Exec(nil, utils.ToCmdLine("GETSET", key, value))
_, ok := actual.(*reply.NullBulkReply) _, ok := actual.(*protocol.NullBulkReply)
if !ok { if !ok {
t.Errorf("expect null bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect null bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -323,9 +323,9 @@ func TestStrLen(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("StrLen", key)) actual := testDB.Exec(nil, utils.ToCmdLine("StrLen", key))
len, ok := actual.(*reply.IntReply) len, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expect int bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect int bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
asserts.AssertIntReply(t, len, 10) asserts.AssertIntReply(t, len, 10)
@@ -336,9 +336,9 @@ func TestStrLen_KeyNotExist(t *testing.T) {
key := utils.RandString(10) key := utils.RandString(10)
actual := testDB.Exec(nil, utils.ToCmdLine("StrLen", key)) actual := testDB.Exec(nil, utils.ToCmdLine("StrLen", key))
result, ok := actual.(*reply.IntReply) result, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expect null bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect null bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -352,9 +352,9 @@ func TestAppend_KeyExist(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("Append", key, key2)) actual := testDB.Exec(nil, utils.ToCmdLine("Append", key, key2))
val, ok := actual.(*reply.IntReply) val, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expect nil bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect nil bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
asserts.AssertIntReply(t, val, len(key)*2) asserts.AssertIntReply(t, val, len(key)*2)
@@ -365,9 +365,9 @@ func TestAppend_KeyNotExist(t *testing.T) {
key := utils.RandString(10) key := utils.RandString(10)
actual := testDB.Exec(nil, utils.ToCmdLine("Append", key, key)) actual := testDB.Exec(nil, utils.ToCmdLine("Append", key, key))
val, ok := actual.(*reply.IntReply) val, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expect nil bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect nil bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
asserts.AssertIntReply(t, val, len(key)) asserts.AssertIntReply(t, val, len(key))
@@ -380,9 +380,9 @@ func TestSetRange_StringExist(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("SetRange", key, fmt.Sprint(0), key2)) actual := testDB.Exec(nil, utils.ToCmdLine("SetRange", key, fmt.Sprint(0), key2))
val, ok := actual.(*reply.IntReply) val, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expect int bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect int bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -398,9 +398,9 @@ func TestSetRange_StringExist_OffsetOutOfLen(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("SetRange", key, fmt.Sprint(len(key)+emptyByteLen), key2)) actual := testDB.Exec(nil, utils.ToCmdLine("SetRange", key, fmt.Sprint(len(key)+emptyByteLen), key2))
val, ok := actual.(*reply.IntReply) val, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expect int bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect int bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -413,9 +413,9 @@ func TestSetRange_StringNotExist(t *testing.T) {
key := utils.RandString(10) key := utils.RandString(10)
actual := testDB.Exec(nil, utils.ToCmdLine("SetRange", key, fmt.Sprint(0), key)) actual := testDB.Exec(nil, utils.ToCmdLine("SetRange", key, fmt.Sprint(0), key))
val, ok := actual.(*reply.IntReply) val, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expect int bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect int bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
asserts.AssertIntReply(t, val, len(key)) asserts.AssertIntReply(t, val, len(key))
@@ -427,9 +427,9 @@ func TestGetRange_StringExist(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key)))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key))))
val, ok := actual.(*reply.BulkReply) val, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -442,9 +442,9 @@ func TestGetRange_RangeLargeThenDataLen(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key)+2))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key)+2)))
val, ok := actual.(*reply.BulkReply) val, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -455,9 +455,9 @@ func TestGetRange_StringNotExist(t *testing.T) {
testDB.Flush() testDB.Flush()
key := utils.RandString(10) key := utils.RandString(10)
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key)))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key))))
val, ok := actual.(*reply.NullBulkReply) val, ok := actual.(*protocol.NullBulkReply)
if !ok { if !ok {
t.Errorf("expect nil bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect nil bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -470,9 +470,9 @@ func TestGetRange_StringExist_GetPartial(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key)/2))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key)/2)))
val, ok := actual.(*reply.BulkReply) val, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -486,9 +486,9 @@ func TestGetRange_StringExist_EndIdxOutOfRange(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key)+emptyByteLen))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(len(key)+emptyByteLen)))
val, ok := actual.(*reply.BulkReply) val, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -502,9 +502,9 @@ func TestGetRange_StringExist_StartIdxEndIdxAreSame(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(len(key)+emptyByteLen), fmt.Sprint(len(key)+emptyByteLen))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(len(key)+emptyByteLen), fmt.Sprint(len(key)+emptyByteLen)))
val, ok := actual.(*reply.NullBulkReply) val, ok := actual.(*protocol.NullBulkReply)
if !ok { if !ok {
t.Errorf("expect nil bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect nil bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -516,9 +516,9 @@ func TestGetRange_StringExist_StartIdxGreaterThanEndIdx(t *testing.T) {
key := utils.RandString(10) key := utils.RandString(10)
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(len(key)+1), fmt.Sprint(len(key)))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(len(key)+1), fmt.Sprint(len(key))))
val, ok := actual.(*reply.NullBulkReply) val, ok := actual.(*protocol.NullBulkReply)
if !ok { if !ok {
t.Errorf("expect nil bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect nil bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -531,9 +531,9 @@ func TestGetRange_StringExist_StartIdxEndIdxAreNegative(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(-1*len(key)), fmt.Sprint(-1))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(-1*len(key)), fmt.Sprint(-1)))
val, ok := actual.(*reply.BulkReply) val, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -546,9 +546,9 @@ func TestGetRange_StringExist_StartIdxNegative(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(-1*len(key)), fmt.Sprint(len(key)/2))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(-1*len(key)), fmt.Sprint(len(key)/2)))
val, ok := actual.(*reply.BulkReply) val, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -561,9 +561,9 @@ func TestGetRange_StringExist_EndIdxNegative(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(-len(key)/2))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(-len(key)/2)))
val, ok := actual.(*reply.BulkReply) val, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -576,9 +576,9 @@ func TestGetRange_StringExist_StartIsOutOfRange(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(-len(key)-3), fmt.Sprint(len(key)))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(-len(key)-3), fmt.Sprint(len(key))))
val, ok := actual.(*reply.NullBulkReply) val, ok := actual.(*protocol.NullBulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -591,9 +591,9 @@ func TestGetRange_StringExist_EndIdxIsOutOfRange(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(-len(key)-3))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), fmt.Sprint(-len(key)-3)))
val, ok := actual.(*reply.NullBulkReply) val, ok := actual.(*protocol.NullBulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -606,9 +606,9 @@ func TestGetRange_StringExist_StartIdxGreaterThanDataLen(t *testing.T) {
testDB.Exec(nil, utils.ToCmdLine2("SET", key, key)) testDB.Exec(nil, utils.ToCmdLine2("SET", key, key))
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(len(key)+1), fmt.Sprint(0))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(len(key)+1), fmt.Sprint(0)))
val, ok := actual.(*reply.NullBulkReply) val, ok := actual.(*protocol.NullBulkReply)
if !ok { if !ok {
t.Errorf("expect bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -622,9 +622,9 @@ func TestGetRange_StringExist_StartIdxIncorrectFormat(t *testing.T) {
incorrectValue := "incorrect" incorrectValue := "incorrect"
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, incorrectValue, fmt.Sprint(0))) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, incorrectValue, fmt.Sprint(0)))
val, ok := actual.(*reply.StandardErrReply) val, ok := actual.(*protocol.StandardErrReply)
if !ok { if !ok {
t.Errorf("expect standart bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect standart bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }
@@ -639,9 +639,9 @@ func TestGetRange_StringExist_EndIdxIncorrectFormat(t *testing.T) {
incorrectValue := "incorrect" incorrectValue := "incorrect"
actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), incorrectValue)) actual := testDB.Exec(nil, utils.ToCmdLine("GetRange", key, fmt.Sprint(0), incorrectValue))
val, ok := actual.(*reply.StandardErrReply) val, ok := actual.(*protocol.StandardErrReply)
if !ok { if !ok {
t.Errorf("expect standart bulk reply, get: %s", string(actual.ToBytes())) t.Errorf("expect standart bulk protocol, get: %s", string(actual.ToBytes()))
return return
} }

View File

@@ -3,34 +3,34 @@ package database
import ( import (
"github.com/hdt3213/godis/config" "github.com/hdt3213/godis/config"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
) )
// Ping the server // Ping the server
func Ping(db *DB, args [][]byte) redis.Reply { func Ping(db *DB, args [][]byte) redis.Reply {
if len(args) == 0 { if len(args) == 0 {
return &reply.PongReply{} return &protocol.PongReply{}
} else if len(args) == 1 { } else if len(args) == 1 {
return reply.MakeStatusReply(string(args[0])) return protocol.MakeStatusReply(string(args[0]))
} else { } else {
return reply.MakeErrReply("ERR wrong number of arguments for 'ping' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'ping' command")
} }
} }
// Auth validate client's password // Auth validate client's password
func Auth(c redis.Connection, args [][]byte) redis.Reply { func Auth(c redis.Connection, args [][]byte) redis.Reply {
if len(args) != 1 { if len(args) != 1 {
return reply.MakeErrReply("ERR wrong number of arguments for 'auth' command") return protocol.MakeErrReply("ERR wrong number of arguments for 'auth' command")
} }
if config.Properties.RequirePass == "" { if config.Properties.RequirePass == "" {
return reply.MakeErrReply("ERR Client sent AUTH, but no password is set") return protocol.MakeErrReply("ERR Client sent AUTH, but no password is set")
} }
passwd := string(args[0]) passwd := string(args[0])
c.SetPassword(passwd) c.SetPassword(passwd)
if config.Properties.RequirePass != passwd { if config.Properties.RequirePass != passwd {
return reply.MakeErrReply("ERR invalid password") return protocol.MakeErrReply("ERR invalid password")
} }
return &reply.OkReply{} return &protocol.OkReply{}
} }
func isAuthenticated(c redis.Connection) bool { func isAuthenticated(c redis.Connection) bool {

View File

@@ -4,7 +4,7 @@ import (
"github.com/hdt3213/godis/config" "github.com/hdt3213/godis/config"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )

View File

@@ -3,7 +3,7 @@ package database
import ( import (
"github.com/hdt3213/godis/datastruct/set" "github.com/hdt3213/godis/datastruct/set"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strings" "strings"
) )
@@ -19,13 +19,13 @@ func Watch(db *DB, conn redis.Connection, args [][]byte) redis.Reply {
key := string(bkey) key := string(bkey)
watching[key] = db.GetVersion(key) watching[key] = db.GetVersion(key)
} }
return reply.MakeOkReply() return protocol.MakeOkReply()
} }
func execGetVersion(db *DB, args [][]byte) redis.Reply { func execGetVersion(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
ver := db.GetVersion(key) ver := db.GetVersion(key)
return reply.MakeIntReply(int64(ver)) return protocol.MakeIntReply(int64(ver))
} }
func init() { func init() {
@@ -46,10 +46,10 @@ func isWatchingChanged(db *DB, watching map[string]uint32) bool {
// StartMulti starts multi-command-transaction // StartMulti starts multi-command-transaction
func StartMulti(conn redis.Connection) redis.Reply { func StartMulti(conn redis.Connection) redis.Reply {
if conn.InMultiState() { if conn.InMultiState() {
return reply.MakeErrReply("ERR MULTI calls can not be nested") return protocol.MakeErrReply("ERR MULTI calls can not be nested")
} }
conn.SetMultiState(true) conn.SetMultiState(true)
return reply.MakeOkReply() return protocol.MakeOkReply()
} }
// EnqueueCmd puts command line into `multi` pending queue // EnqueueCmd puts command line into `multi` pending queue
@@ -57,25 +57,25 @@ func EnqueueCmd(conn redis.Connection, cmdLine [][]byte) redis.Reply {
cmdName := strings.ToLower(string(cmdLine[0])) cmdName := strings.ToLower(string(cmdLine[0]))
cmd, ok := cmdTable[cmdName] cmd, ok := cmdTable[cmdName]
if !ok { if !ok {
return reply.MakeErrReply("ERR unknown command '" + cmdName + "'") return protocol.MakeErrReply("ERR unknown command '" + cmdName + "'")
} }
if forbiddenInMulti.Has(cmdName) { if forbiddenInMulti.Has(cmdName) {
return reply.MakeErrReply("ERR command '" + cmdName + "' cannot be used in MULTI") return protocol.MakeErrReply("ERR command '" + cmdName + "' cannot be used in MULTI")
} }
if cmd.prepare == nil { if cmd.prepare == nil {
return reply.MakeErrReply("ERR command '" + cmdName + "' cannot be used in MULTI") return protocol.MakeErrReply("ERR command '" + cmdName + "' cannot be used in MULTI")
} }
if !validateArity(cmd.arity, cmdLine) { if !validateArity(cmd.arity, cmdLine) {
// difference with redis: we won't enqueue command line with wrong arity // difference with redis: we won't enqueue command line with wrong arity
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
conn.EnqueueCmd(cmdLine) conn.EnqueueCmd(cmdLine)
return reply.MakeQueuedReply() return protocol.MakeQueuedReply()
} }
func execMulti(db *DB, conn redis.Connection) redis.Reply { func execMulti(db *DB, conn redis.Connection) redis.Reply {
if !conn.InMultiState() { if !conn.InMultiState() {
return reply.MakeErrReply("ERR EXEC without MULTI") return protocol.MakeErrReply("ERR EXEC without MULTI")
} }
defer conn.SetMultiState(false) defer conn.SetMultiState(false)
cmdLines := conn.GetQueuedCmdLine() cmdLines := conn.GetQueuedCmdLine()
@@ -105,7 +105,7 @@ func (db *DB) ExecMulti(conn redis.Connection, watching map[string]uint32, cmdLi
defer db.RWUnLocks(writeKeys, readKeys) defer db.RWUnLocks(writeKeys, readKeys)
if isWatchingChanged(db, watching) { // watching keys changed, abort if isWatchingChanged(db, watching) { // watching keys changed, abort
return reply.MakeEmptyMultiBulkReply() return protocol.MakeEmptyMultiBulkReply()
} }
// execute // execute
results := make([]redis.Reply, 0, len(cmdLines)) results := make([]redis.Reply, 0, len(cmdLines))
@@ -114,7 +114,7 @@ func (db *DB) ExecMulti(conn redis.Connection, watching map[string]uint32, cmdLi
for _, cmdLine := range cmdLines { for _, cmdLine := range cmdLines {
undoCmdLines = append(undoCmdLines, db.GetUndoLogs(cmdLine)) undoCmdLines = append(undoCmdLines, db.GetUndoLogs(cmdLine))
result := db.execWithLock(cmdLine) result := db.execWithLock(cmdLine)
if reply.IsErrorReply(result) { if protocol.IsErrorReply(result) {
aborted = true aborted = true
// don't rollback failed commands // don't rollback failed commands
undoCmdLines = undoCmdLines[:len(undoCmdLines)-1] undoCmdLines = undoCmdLines[:len(undoCmdLines)-1]
@@ -124,7 +124,7 @@ func (db *DB) ExecMulti(conn redis.Connection, watching map[string]uint32, cmdLi
} }
if !aborted { //success if !aborted { //success
db.addVersion(writeKeys...) db.addVersion(writeKeys...)
return reply.MakeMultiRawReply(results) return protocol.MakeMultiRawReply(results)
} }
// undo if aborted // undo if aborted
size := len(undoCmdLines) size := len(undoCmdLines)
@@ -137,17 +137,17 @@ func (db *DB) ExecMulti(conn redis.Connection, watching map[string]uint32, cmdLi
db.execWithLock(cmdLine) db.execWithLock(cmdLine)
} }
} }
return reply.MakeErrReply("EXECABORT Transaction discarded because of previous errors.") return protocol.MakeErrReply("EXECABORT Transaction discarded because of previous errors.")
} }
// DiscardMulti drops MULTI pending commands // DiscardMulti drops MULTI pending commands
func DiscardMulti(conn redis.Connection) redis.Reply { func DiscardMulti(conn redis.Connection) redis.Reply {
if !conn.InMultiState() { if !conn.InMultiState() {
return reply.MakeErrReply("ERR DISCARD without MULTI") return protocol.MakeErrReply("ERR DISCARD without MULTI")
} }
conn.ClearQueuedCmds() conn.ClearQueuedCmds()
conn.SetMultiState(false) conn.SetMultiState(false)
return reply.MakeOkReply() return protocol.MakeOkReply()
} }
// GetUndoLogs return rollback commands // GetUndoLogs return rollback commands
@@ -169,10 +169,10 @@ func (db *DB) execWithLock(cmdLine [][]byte) redis.Reply {
cmdName := strings.ToLower(string(cmdLine[0])) cmdName := strings.ToLower(string(cmdLine[0]))
cmd, ok := cmdTable[cmdName] cmd, ok := cmdTable[cmdName]
if !ok { if !ok {
return reply.MakeErrReply("ERR unknown command '" + cmdName + "'") return protocol.MakeErrReply("ERR unknown command '" + cmdName + "'")
} }
if !validateArity(cmd.arity, cmdLine) { if !validateArity(cmd.arity, cmdLine) {
return reply.MakeArgNumErrReply(cmdName) return protocol.MakeArgNumErrReply(cmdName)
} }
fun := cmd.executor fun := cmd.executor
return fun(db, cmdLine[1:]) return fun(db, cmdLine[1:])

View File

@@ -3,7 +3,7 @@ package database
import ( import (
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )

View File

@@ -2,7 +2,7 @@ package database
import ( import (
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
"time" "time"
) )

View File

@@ -3,7 +3,7 @@ package pubsub
import ( import (
"github.com/hdt3213/godis/datastruct/list" "github.com/hdt3213/godis/datastruct/list"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
) )
@@ -15,9 +15,9 @@ var (
) )
func makeMsg(t string, channel string, code int64) []byte { func makeMsg(t string, channel string, code int64) []byte {
return []byte("*3\r\n$" + strconv.FormatInt(int64(len(t)), 10) + reply.CRLF + t + reply.CRLF + return []byte("*3\r\n$" + strconv.FormatInt(int64(len(t)), 10) + protocol.CRLF + t + protocol.CRLF +
"$" + strconv.FormatInt(int64(len(channel)), 10) + reply.CRLF + channel + reply.CRLF + "$" + strconv.FormatInt(int64(len(channel)), 10) + protocol.CRLF + channel + protocol.CRLF +
":" + strconv.FormatInt(code, 10) + reply.CRLF) ":" + strconv.FormatInt(code, 10) + protocol.CRLF)
} }
/* /*
@@ -80,7 +80,7 @@ func Subscribe(hub *Hub, c redis.Connection, args [][]byte) redis.Reply {
_ = c.Write(makeMsg(_subscribe, channel, int64(c.SubsCount()))) _ = c.Write(makeMsg(_subscribe, channel, int64(c.SubsCount())))
} }
} }
return &reply.NoReply{} return &protocol.NoReply{}
} }
// UnsubscribeAll removes the given connection from all subscribing channel // UnsubscribeAll removes the given connection from all subscribing channel
@@ -113,7 +113,7 @@ func UnSubscribe(db *Hub, c redis.Connection, args [][]byte) redis.Reply {
if len(channels) == 0 { if len(channels) == 0 {
_ = c.Write(unSubscribeNothing) _ = c.Write(unSubscribeNothing)
return &reply.NoReply{} return &protocol.NoReply{}
} }
for _, channel := range channels { for _, channel := range channels {
@@ -121,13 +121,13 @@ func UnSubscribe(db *Hub, c redis.Connection, args [][]byte) redis.Reply {
_ = c.Write(makeMsg(_unsubscribe, channel, int64(c.SubsCount()))) _ = c.Write(makeMsg(_unsubscribe, channel, int64(c.SubsCount())))
} }
} }
return &reply.NoReply{} return &protocol.NoReply{}
} }
// Publish send msg to all subscribing client // Publish send msg to all subscribing client
func Publish(hub *Hub, args [][]byte) redis.Reply { func Publish(hub *Hub, args [][]byte) redis.Reply {
if len(args) != 2 { if len(args) != 2 {
return &reply.ArgNumErrReply{Cmd: "publish"} return &protocol.ArgNumErrReply{Cmd: "publish"}
} }
channel := string(args[0]) channel := string(args[0])
message := args[1] message := args[1]
@@ -137,7 +137,7 @@ func Publish(hub *Hub, args [][]byte) redis.Reply {
raw, ok := hub.subs.Get(channel) raw, ok := hub.subs.Get(channel)
if !ok { if !ok {
return reply.MakeIntReply(0) return protocol.MakeIntReply(0)
} }
subscribers, _ := raw.(*list.LinkedList) subscribers, _ := raw.(*list.LinkedList)
subscribers.ForEach(func(i int, c interface{}) bool { subscribers.ForEach(func(i int, c interface{}) bool {
@@ -146,8 +146,8 @@ func Publish(hub *Hub, args [][]byte) redis.Reply {
replyArgs[0] = messageBytes replyArgs[0] = messageBytes
replyArgs[1] = []byte(channel) replyArgs[1] = []byte(channel)
replyArgs[2] = message replyArgs[2] = message
_ = client.Write(reply.MakeMultiBulkReply(replyArgs).ToBytes()) _ = client.Write(protocol.MakeMultiBulkReply(replyArgs).ToBytes())
return true return true
}) })
return reply.MakeIntReply(int64(subscribers.Len())) return protocol.MakeIntReply(int64(subscribers.Len()))
} }

View File

@@ -5,7 +5,7 @@ import (
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/lib/sync/wait" "github.com/hdt3213/godis/lib/sync/wait"
"github.com/hdt3213/godis/redis/parser" "github.com/hdt3213/godis/redis/parser"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"net" "net"
"runtime/debug" "runtime/debug"
"sync" "sync"
@@ -128,10 +128,10 @@ func (client *Client) Send(args [][]byte) redis.Reply {
client.pendingReqs <- request client.pendingReqs <- request
timeout := request.waiting.WaitWithTimeout(maxWait) timeout := request.waiting.WaitWithTimeout(maxWait)
if timeout { if timeout {
return reply.MakeErrReply("server time out") return protocol.MakeErrReply("server time out")
} }
if request.err != nil { if request.err != nil {
return reply.MakeErrReply("request failed") return protocol.MakeErrReply("request failed")
} }
return request.reply return request.reply
} }
@@ -153,7 +153,7 @@ func (client *Client) doRequest(req *request) {
if req == nil || len(req.args) == 0 { if req == nil || len(req.args) == 0 {
return return
} }
re := reply.MakeMultiBulkReply(req.args) re := protocol.MakeMultiBulkReply(req.args)
bytes := re.ToBytes() bytes := re.ToBytes()
_, err := client.conn.Write(bytes) _, err := client.conn.Write(bytes)
i := 0 i := 0
@@ -193,7 +193,7 @@ func (client *Client) handleRead() error {
ch := parser.ParseStream(client.conn) ch := parser.ParseStream(client.conn)
for payload := range ch { for payload := range ch {
if payload.Err != nil { if payload.Err != nil {
client.finishRequest(reply.MakeErrReply(payload.Err.Error())) client.finishRequest(protocol.MakeErrReply(payload.Err.Error()))
continue continue
} }
client.finishRequest(payload.Data) client.finishRequest(payload.Data)

View File

@@ -2,7 +2,7 @@ package client
import ( import (
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"strconv" "strconv"
"testing" "testing"
) )
@@ -23,7 +23,7 @@ func TestClient(t *testing.T) {
result := client.Send([][]byte{ result := client.Send([][]byte{
[]byte("PING"), []byte("PING"),
}) })
if statusRet, ok := result.(*reply.StatusReply); ok { if statusRet, ok := result.(*protocol.StatusReply); ok {
if statusRet.Status != "PONG" { if statusRet.Status != "PONG" {
t.Error("`ping` failed, result: " + statusRet.Status) t.Error("`ping` failed, result: " + statusRet.Status)
} }
@@ -34,7 +34,7 @@ func TestClient(t *testing.T) {
[]byte("a"), []byte("a"),
[]byte("a"), []byte("a"),
}) })
if statusRet, ok := result.(*reply.StatusReply); ok { if statusRet, ok := result.(*protocol.StatusReply); ok {
if statusRet.Status != "OK" { if statusRet.Status != "OK" {
t.Error("`set` failed, result: " + statusRet.Status) t.Error("`set` failed, result: " + statusRet.Status)
} }
@@ -44,7 +44,7 @@ func TestClient(t *testing.T) {
[]byte("GET"), []byte("GET"),
[]byte("a"), []byte("a"),
}) })
if bulkRet, ok := result.(*reply.BulkReply); ok { if bulkRet, ok := result.(*protocol.BulkReply); ok {
if string(bulkRet.Arg) != "a" { if string(bulkRet.Arg) != "a" {
t.Error("`get` failed, result: " + string(bulkRet.Arg)) t.Error("`get` failed, result: " + string(bulkRet.Arg))
} }
@@ -54,7 +54,7 @@ func TestClient(t *testing.T) {
[]byte("DEL"), []byte("DEL"),
[]byte("a"), []byte("a"),
}) })
if intRet, ok := result.(*reply.IntReply); ok { if intRet, ok := result.(*protocol.IntReply); ok {
if intRet.Code != 1 { if intRet.Code != 1 {
t.Error("`del` failed, result: " + strconv.FormatInt(intRet.Code, 10)) t.Error("`del` failed, result: " + strconv.FormatInt(intRet.Code, 10))
} }
@@ -65,7 +65,7 @@ func TestClient(t *testing.T) {
[]byte("GET"), []byte("GET"),
[]byte("a"), []byte("a"),
}) })
if _, ok := result.(*reply.NullBulkReply); !ok { if _, ok := result.(*protocol.NullBulkReply); !ok {
t.Error("`get` failed, result: " + string(result.ToBytes())) t.Error("`get` failed, result: " + string(result.ToBytes()))
} }
@@ -81,7 +81,7 @@ func TestClient(t *testing.T) {
[]byte("2"), []byte("2"),
[]byte("c"), []byte("c"),
}) })
if intRet, ok := result.(*reply.IntReply); ok { if intRet, ok := result.(*protocol.IntReply); ok {
if intRet.Code != 3 { if intRet.Code != 3 {
t.Error("`rpush` failed, result: " + strconv.FormatInt(intRet.Code, 10)) t.Error("`rpush` failed, result: " + strconv.FormatInt(intRet.Code, 10))
} }
@@ -93,7 +93,7 @@ func TestClient(t *testing.T) {
[]byte("0"), []byte("0"),
[]byte("-1"), []byte("-1"),
}) })
if multiBulkRet, ok := result.(*reply.MultiBulkReply); ok { if multiBulkRet, ok := result.(*protocol.MultiBulkReply); ok {
if len(multiBulkRet.Args) != 3 || if len(multiBulkRet.Args) != 3 ||
string(multiBulkRet.Args[0]) != "1" || string(multiBulkRet.Args[0]) != "1" ||
string(multiBulkRet.Args[1]) != "2" || string(multiBulkRet.Args[1]) != "2" ||

View File

@@ -12,7 +12,7 @@ import (
type Connection struct { type Connection struct {
conn net.Conn conn net.Conn
// waiting until reply finished // waiting until protocol finished
waitingReply wait.Wait waitingReply wait.Wait
// lock while server sending response // lock while server sending response

View File

@@ -6,7 +6,7 @@ import (
"errors" "errors"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/logger" "github.com/hdt3213/godis/lib/logger"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"io" "io"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
@@ -34,7 +34,7 @@ func ParseBytes(data []byte) ([]redis.Reply, error) {
var results []redis.Reply var results []redis.Reply
for payload := range ch { for payload := range ch {
if payload == nil { if payload == nil {
return nil, errors.New("no reply") return nil, errors.New("no protocol")
} }
if payload.Err != nil { if payload.Err != nil {
if payload.Err == io.EOF { if payload.Err == io.EOF {
@@ -54,7 +54,7 @@ func ParseOne(data []byte) (redis.Reply, error) {
go parse0(reader, ch) go parse0(reader, ch)
payload := <-ch // parse0 will close the channel payload := <-ch // parse0 will close the channel
if payload == nil { if payload == nil {
return nil, errors.New("no reply") return nil, errors.New("no protocol")
} }
return payload.Data, payload.Err return payload.Data, payload.Err
} }
@@ -105,7 +105,7 @@ func parse0(reader io.Reader, ch chan<- *Payload) {
if !state.readingMultiLine { if !state.readingMultiLine {
// receive new response // receive new response
if msg[0] == '*' { if msg[0] == '*' {
// multi bulk reply // multi bulk protocol
err = parseMultiBulkHeader(msg, &state) err = parseMultiBulkHeader(msg, &state)
if err != nil { if err != nil {
ch <- &Payload{ ch <- &Payload{
@@ -116,12 +116,12 @@ func parse0(reader io.Reader, ch chan<- *Payload) {
} }
if state.expectedArgsCount == 0 { if state.expectedArgsCount == 0 {
ch <- &Payload{ ch <- &Payload{
Data: &reply.EmptyMultiBulkReply{}, Data: &protocol.EmptyMultiBulkReply{},
} }
state = readState{} // reset state state = readState{} // reset state
continue continue
} }
} else if msg[0] == '$' { // bulk reply } else if msg[0] == '$' { // bulk protocol
err = parseBulkHeader(msg, &state) err = parseBulkHeader(msg, &state)
if err != nil { if err != nil {
ch <- &Payload{ ch <- &Payload{
@@ -130,15 +130,15 @@ func parse0(reader io.Reader, ch chan<- *Payload) {
state = readState{} // reset state state = readState{} // reset state
continue continue
} }
if state.bulkLen == -1 { // null bulk reply if state.bulkLen == -1 { // null bulk protocol
ch <- &Payload{ ch <- &Payload{
Data: &reply.NullBulkReply{}, Data: &protocol.NullBulkReply{},
} }
state = readState{} // reset state state = readState{} // reset state
continue continue
} }
} else { } else {
// single line reply // single line protocol
result, err := parseSingleLineReply(msg) result, err := parseSingleLineReply(msg)
ch <- &Payload{ ch <- &Payload{
Data: result, Data: result,
@@ -148,7 +148,7 @@ func parse0(reader io.Reader, ch chan<- *Payload) {
continue continue
} }
} else { } else {
// receive following bulk reply // receive following bulk protocol
err = readBody(msg, &state) err = readBody(msg, &state)
if err != nil { if err != nil {
ch <- &Payload{ ch <- &Payload{
@@ -161,9 +161,9 @@ func parse0(reader io.Reader, ch chan<- *Payload) {
if state.finished() { if state.finished() {
var result redis.Reply var result redis.Reply
if state.msgType == '*' { if state.msgType == '*' {
result = reply.MakeMultiBulkReply(state.args) result = protocol.MakeMultiBulkReply(state.args)
} else if state.msgType == '$' { } else if state.msgType == '$' {
result = reply.MakeBulkReply(state.args[0]) result = protocol.MakeBulkReply(state.args[0])
} }
ch <- &Payload{ ch <- &Payload{
Data: result, Data: result,
@@ -213,7 +213,7 @@ func parseMultiBulkHeader(msg []byte, state *readState) error {
state.expectedArgsCount = 0 state.expectedArgsCount = 0
return nil return nil
} else if expectedLine > 0 { } else if expectedLine > 0 {
// first line of multi bulk reply // first line of multi bulk protocol
state.msgType = msg[0] state.msgType = msg[0]
state.readingMultiLine = true state.readingMultiLine = true
state.expectedArgsCount = int(expectedLine) state.expectedArgsCount = int(expectedLine)
@@ -247,16 +247,16 @@ func parseSingleLineReply(msg []byte) (redis.Reply, error) {
str := strings.TrimSuffix(string(msg), "\r\n") str := strings.TrimSuffix(string(msg), "\r\n")
var result redis.Reply var result redis.Reply
switch msg[0] { switch msg[0] {
case '+': // status reply case '+': // status protocol
result = reply.MakeStatusReply(str[1:]) result = protocol.MakeStatusReply(str[1:])
case '-': // err reply case '-': // err protocol
result = reply.MakeErrReply(str[1:]) result = protocol.MakeErrReply(str[1:])
case ':': // int reply case ':': // int protocol
val, err := strconv.ParseInt(str[1:], 10, 64) val, err := strconv.ParseInt(str[1:], 10, 64)
if err != nil { if err != nil {
return nil, errors.New("protocol error: " + string(msg)) return nil, errors.New("protocol error: " + string(msg))
} }
result = reply.MakeIntReply(val) result = protocol.MakeIntReply(val)
default: default:
// parse as text protocol // parse as text protocol
strs := strings.Split(str, " ") strs := strings.Split(str, " ")
@@ -264,17 +264,17 @@ func parseSingleLineReply(msg []byte) (redis.Reply, error) {
for i, s := range strs { for i, s := range strs {
args[i] = []byte(s) args[i] = []byte(s)
} }
result = reply.MakeMultiBulkReply(args) result = protocol.MakeMultiBulkReply(args)
} }
return result, nil return result, nil
} }
// read the non-first lines of multi bulk reply or bulk reply // read the non-first lines of multi bulk protocol or bulk protocol
func readBody(msg []byte, state *readState) error { func readBody(msg []byte, state *readState) error {
line := msg[0 : len(msg)-2] line := msg[0 : len(msg)-2]
var err error var err error
if line[0] == '$' { if line[0] == '$' {
// bulk reply // bulk protocol
state.bulkLen, err = strconv.ParseInt(string(line[1:]), 10, 64) state.bulkLen, err = strconv.ParseInt(string(line[1:]), 10, 64)
if err != nil { if err != nil {
return errors.New("protocol error: " + string(msg)) return errors.New("protocol error: " + string(msg))

View File

@@ -4,32 +4,32 @@ import (
"bytes" "bytes"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"io" "io"
"testing" "testing"
) )
func TestParseStream(t *testing.T) { func TestParseStream(t *testing.T) {
replies := []redis.Reply{ replies := []redis.Reply{
reply.MakeIntReply(1), protocol.MakeIntReply(1),
reply.MakeStatusReply("OK"), protocol.MakeStatusReply("OK"),
reply.MakeErrReply("ERR unknown"), protocol.MakeErrReply("ERR unknown"),
reply.MakeBulkReply([]byte("a\r\nb")), // test binary safe protocol.MakeBulkReply([]byte("a\r\nb")), // test binary safe
reply.MakeNullBulkReply(), protocol.MakeNullBulkReply(),
reply.MakeMultiBulkReply([][]byte{ protocol.MakeMultiBulkReply([][]byte{
[]byte("a"), []byte("a"),
[]byte("\r\n"), []byte("\r\n"),
}), }),
reply.MakeEmptyMultiBulkReply(), protocol.MakeEmptyMultiBulkReply(),
} }
reqs := bytes.Buffer{} reqs := bytes.Buffer{}
for _, re := range replies { for _, re := range replies {
reqs.Write(re.ToBytes()) reqs.Write(re.ToBytes())
} }
reqs.Write([]byte("set a a" + reply.CRLF)) // test text protocol reqs.Write([]byte("set a a" + protocol.CRLF)) // test text protocol
expected := make([]redis.Reply, len(replies)) expected := make([]redis.Reply, len(replies))
copy(expected, replies) copy(expected, replies)
expected = append(expected, reply.MakeMultiBulkReply([][]byte{ expected = append(expected, protocol.MakeMultiBulkReply([][]byte{
[]byte("set"), []byte("a"), []byte("a"), []byte("set"), []byte("a"), []byte("a"),
})) }))
@@ -57,16 +57,16 @@ func TestParseStream(t *testing.T) {
func TestParseOne(t *testing.T) { func TestParseOne(t *testing.T) {
replies := []redis.Reply{ replies := []redis.Reply{
reply.MakeIntReply(1), protocol.MakeIntReply(1),
reply.MakeStatusReply("OK"), protocol.MakeStatusReply("OK"),
reply.MakeErrReply("ERR unknown"), protocol.MakeErrReply("ERR unknown"),
reply.MakeBulkReply([]byte("a\r\nb")), // test binary safe protocol.MakeBulkReply([]byte("a\r\nb")), // test binary safe
reply.MakeNullBulkReply(), protocol.MakeNullBulkReply(),
reply.MakeMultiBulkReply([][]byte{ protocol.MakeMultiBulkReply([][]byte{
[]byte("a"), []byte("a"),
[]byte("\r\n"), []byte("\r\n"),
}), }),
reply.MakeEmptyMultiBulkReply(), protocol.MakeEmptyMultiBulkReply(),
} }
for _, re := range replies { for _, re := range replies {
result, err := ParseOne(re.ToBytes()) result, err := ParseOne(re.ToBytes())

View File

@@ -4,16 +4,16 @@ import (
"fmt" "fmt"
"github.com/hdt3213/godis/interface/redis" "github.com/hdt3213/godis/interface/redis"
"github.com/hdt3213/godis/lib/utils" "github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"runtime" "runtime"
"testing" "testing"
) )
// AssertIntReply checks if the given redis.Reply is the expected integer // AssertIntReply checks if the given redis.Reply is the expected integer
func AssertIntReply(t *testing.T, actual redis.Reply, expected int) { func AssertIntReply(t *testing.T, actual redis.Reply, expected int) {
intResult, ok := actual.(*reply.IntReply) intResult, ok := actual.(*protocol.IntReply)
if !ok { if !ok {
t.Errorf("expected int reply, actually %s, %s", actual.ToBytes(), printStack()) t.Errorf("expected int protocol, actually %s, %s", actual.ToBytes(), printStack())
return return
} }
if intResult.Code != int64(expected) { if intResult.Code != int64(expected) {
@@ -23,9 +23,9 @@ func AssertIntReply(t *testing.T, actual redis.Reply, expected int) {
// AssertBulkReply checks if the given redis.Reply is the expected string // AssertBulkReply checks if the given redis.Reply is the expected string
func AssertBulkReply(t *testing.T, actual redis.Reply, expected string) { func AssertBulkReply(t *testing.T, actual redis.Reply, expected string) {
bulkReply, ok := actual.(*reply.BulkReply) bulkReply, ok := actual.(*protocol.BulkReply)
if !ok { if !ok {
t.Errorf("expected bulk reply, actually %s, %s", actual.ToBytes(), printStack()) t.Errorf("expected bulk protocol, actually %s, %s", actual.ToBytes(), printStack())
return return
} }
if !utils.BytesEquals(bulkReply.Arg, []byte(expected)) { if !utils.BytesEquals(bulkReply.Arg, []byte(expected)) {
@@ -35,14 +35,14 @@ func AssertBulkReply(t *testing.T, actual redis.Reply, expected string) {
// AssertStatusReply checks if the given redis.Reply is the expected status // AssertStatusReply checks if the given redis.Reply is the expected status
func AssertStatusReply(t *testing.T, actual redis.Reply, expected string) { func AssertStatusReply(t *testing.T, actual redis.Reply, expected string) {
statusReply, ok := actual.(*reply.StatusReply) statusReply, ok := actual.(*protocol.StatusReply)
if !ok { if !ok {
// may be a reply.OkReply e.g. // may be a protocol.OkReply e.g.
expectBytes := reply.MakeStatusReply(expected).ToBytes() expectBytes := protocol.MakeStatusReply(expected).ToBytes()
if utils.BytesEquals(actual.ToBytes(), expectBytes) { if utils.BytesEquals(actual.ToBytes(), expectBytes) {
return return
} }
t.Errorf("expected bulk reply, actually %s, %s", actual.ToBytes(), printStack()) t.Errorf("expected bulk protocol, actually %s, %s", actual.ToBytes(), printStack())
return return
} }
if statusReply.Status != expected { if statusReply.Status != expected {
@@ -52,13 +52,13 @@ func AssertStatusReply(t *testing.T, actual redis.Reply, expected string) {
// AssertErrReply checks if the given redis.Reply is the expected error // AssertErrReply checks if the given redis.Reply is the expected error
func AssertErrReply(t *testing.T, actual redis.Reply, expected string) { func AssertErrReply(t *testing.T, actual redis.Reply, expected string) {
errReply, ok := actual.(reply.ErrorReply) errReply, ok := actual.(protocol.ErrorReply)
if !ok { if !ok {
expectBytes := reply.MakeErrReply(expected).ToBytes() expectBytes := protocol.MakeErrReply(expected).ToBytes()
if utils.BytesEquals(actual.ToBytes(), expectBytes) { if utils.BytesEquals(actual.ToBytes(), expectBytes) {
return return
} }
t.Errorf("expected err reply, actually %s, %s", actual.ToBytes(), printStack()) t.Errorf("expected err protocol, actually %s, %s", actual.ToBytes(), printStack())
return return
} }
if errReply.Error() != expected { if errReply.Error() != expected {
@@ -66,7 +66,7 @@ func AssertErrReply(t *testing.T, actual redis.Reply, expected string) {
} }
} }
// AssertNotError checks if the given redis.Reply is not error reply // AssertNotError checks if the given redis.Reply is not error protocol
func AssertNotError(t *testing.T, result redis.Reply) { func AssertNotError(t *testing.T, result redis.Reply) {
if result == nil { if result == nil {
t.Errorf("result is nil %s", printStack()) t.Errorf("result is nil %s", printStack())
@@ -78,11 +78,11 @@ func AssertNotError(t *testing.T, result redis.Reply) {
return return
} }
if bytes[0] == '-' { if bytes[0] == '-' {
t.Errorf("result is err reply %s", printStack()) t.Errorf("result is err protocol %s", printStack())
} }
} }
// AssertNullBulk checks if the given redis.Reply is reply.NullBulkReply // AssertNullBulk checks if the given redis.Reply is protocol.NullBulkReply
func AssertNullBulk(t *testing.T, result redis.Reply) { func AssertNullBulk(t *testing.T, result redis.Reply) {
if result == nil { if result == nil {
t.Errorf("result is nil %s", printStack()) t.Errorf("result is nil %s", printStack())
@@ -93,17 +93,17 @@ func AssertNullBulk(t *testing.T, result redis.Reply) {
t.Errorf("result is empty %s", printStack()) t.Errorf("result is empty %s", printStack())
return return
} }
expect := (&reply.NullBulkReply{}).ToBytes() expect := (&protocol.NullBulkReply{}).ToBytes()
if !utils.BytesEquals(expect, bytes) { if !utils.BytesEquals(expect, bytes) {
t.Errorf("result is not null-bulk-reply %s", printStack()) t.Errorf("result is not null-bulk-protocol %s", printStack())
} }
} }
// AssertMultiBulkReply checks if the given redis.Reply has the expected content // AssertMultiBulkReply checks if the given redis.Reply has the expected content
func AssertMultiBulkReply(t *testing.T, actual redis.Reply, expected []string) { func AssertMultiBulkReply(t *testing.T, actual redis.Reply, expected []string) {
multiBulk, ok := actual.(*reply.MultiBulkReply) multiBulk, ok := actual.(*protocol.MultiBulkReply)
if !ok { if !ok {
t.Errorf("expected bulk reply, actually %s, %s", actual.ToBytes(), printStack()) t.Errorf("expected bulk protocol, actually %s, %s", actual.ToBytes(), printStack())
return return
} }
if len(multiBulk.Args) != len(expected) { if len(multiBulk.Args) != len(expected) {
@@ -121,13 +121,13 @@ func AssertMultiBulkReply(t *testing.T, actual redis.Reply, expected []string) {
// AssertMultiBulkReplySize check if redis.Reply has expected length // AssertMultiBulkReplySize check if redis.Reply has expected length
func AssertMultiBulkReplySize(t *testing.T, actual redis.Reply, expected int) { func AssertMultiBulkReplySize(t *testing.T, actual redis.Reply, expected int) {
multiBulk, ok := actual.(*reply.MultiBulkReply) multiBulk, ok := actual.(*protocol.MultiBulkReply)
if !ok { if !ok {
if expected == 0 && if expected == 0 &&
utils.BytesEquals(actual.ToBytes(), reply.MakeEmptyMultiBulkReply().ToBytes()) { utils.BytesEquals(actual.ToBytes(), protocol.MakeEmptyMultiBulkReply().ToBytes()) {
return return
} }
t.Errorf("expected bulk reply, actually %s, %s", actual.ToBytes(), printStack()) t.Errorf("expected bulk protocol, actually %s, %s", actual.ToBytes(), printStack())
return return
} }
if len(multiBulk.Args) != expected { if len(multiBulk.Args) != expected {

View File

@@ -1,4 +1,4 @@
package reply package protocol
// PongReply is +PONG // PongReply is +PONG
type PongReply struct{} type PongReply struct{}
@@ -22,7 +22,7 @@ func (r *OkReply) ToBytes() []byte {
var theOkReply = new(OkReply) var theOkReply = new(OkReply)
// MakeOkReply returns a ok reply // MakeOkReply returns a ok protocol
func MakeOkReply() *OkReply { func MakeOkReply() *OkReply {
return theOkReply return theOkReply
} }
@@ -79,7 +79,7 @@ func (r *QueuedReply) ToBytes() []byte {
var theQueuedReply = new(QueuedReply) var theQueuedReply = new(QueuedReply)
// MakeQueuedReply returns a QUEUED reply // MakeQueuedReply returns a QUEUED protocol
func MakeQueuedReply() *QueuedReply { func MakeQueuedReply() *QueuedReply {
return theQueuedReply return theQueuedReply
} }

View File

@@ -1,4 +1,4 @@
package reply package protocol
// UnknownErrReply represents UnknownErr // UnknownErrReply represents UnknownErr
type UnknownErrReply struct{} type UnknownErrReply struct{}

View File

@@ -1,4 +1,4 @@
package reply package protocol
import ( import (
"bytes" "bytes"
@@ -115,7 +115,7 @@ type IntReply struct {
Code int64 Code int64
} }
// MakeIntReply creates int reply // MakeIntReply creates int protocol
func MakeIntReply(code int64) *IntReply { func MakeIntReply(code int64) *IntReply {
return &IntReply{ return &IntReply{
Code: code, Code: code,
@@ -147,7 +147,7 @@ func MakeErrReply(status string) *StandardErrReply {
} }
} }
// IsErrorReply returns true if the given reply is error // IsErrorReply returns true if the given protocol is error
func IsErrorReply(reply redis.Reply) bool { func IsErrorReply(reply redis.Reply) bool {
return reply.ToBytes()[0] == '-' return reply.ToBytes()[0] == '-'
} }

View File

@@ -5,7 +5,7 @@ import (
"github.com/hdt3213/godis/pubsub" "github.com/hdt3213/godis/pubsub"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/parser" "github.com/hdt3213/godis/redis/parser"
"github.com/hdt3213/godis/redis/reply/asserts" "github.com/hdt3213/godis/redis/protocol/asserts"
"testing" "testing"
) )

View File

@@ -14,7 +14,7 @@ import (
"github.com/hdt3213/godis/lib/sync/atomic" "github.com/hdt3213/godis/lib/sync/atomic"
"github.com/hdt3213/godis/redis/connection" "github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/parser" "github.com/hdt3213/godis/redis/parser"
"github.com/hdt3213/godis/redis/reply" "github.com/hdt3213/godis/redis/protocol"
"io" "io"
"net" "net"
"strings" "strings"
@@ -75,7 +75,7 @@ func (h *Handler) Handle(ctx context.Context, conn net.Conn) {
return return
} }
// protocol err // protocol err
errReply := reply.MakeErrReply(payload.Err.Error()) errReply := protocol.MakeErrReply(payload.Err.Error())
err := client.Write(errReply.ToBytes()) err := client.Write(errReply.ToBytes())
if err != nil { if err != nil {
h.closeClient(client) h.closeClient(client)
@@ -88,9 +88,9 @@ func (h *Handler) Handle(ctx context.Context, conn net.Conn) {
logger.Error("empty payload") logger.Error("empty payload")
continue continue
} }
r, ok := payload.Data.(*reply.MultiBulkReply) r, ok := payload.Data.(*protocol.MultiBulkReply)
if !ok { if !ok {
logger.Error("require multi bulk reply") logger.Error("require multi bulk protocol")
continue continue
} }
result := h.db.Exec(client, r.Args) result := h.db.Exec(client, r.Args)