mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-05 08:46:56 +08:00
add ltrim command and linsert comnand to list
This commit is contained in:
@@ -50,6 +50,8 @@
|
|||||||
- lindex
|
- lindex
|
||||||
- lset
|
- lset
|
||||||
- lrange
|
- lrange
|
||||||
|
- ltrim
|
||||||
|
- linsert
|
||||||
- Hash
|
- Hash
|
||||||
- hset
|
- hset
|
||||||
- hsetnx
|
- hsetnx
|
||||||
|
101
database/list.go
101
database/list.go
@@ -1,12 +1,15 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
List "github.com/hdt3213/godis/datastruct/list"
|
List "github.com/hdt3213/godis/datastruct/list"
|
||||||
"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/protocol"
|
"github.com/hdt3213/godis/redis/protocol"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db *DB) getAsList(key string) (List.List, protocol.ErrorReply) {
|
func (db *DB) getAsList(key string) (List.List, protocol.ErrorReply) {
|
||||||
@@ -510,6 +513,98 @@ func execRPushX(db *DB, args [][]byte) redis.Reply {
|
|||||||
return protocol.MakeIntReply(int64(list.Len()))
|
return protocol.MakeIntReply(int64(list.Len()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// execLTrim removes elements from both ends a list. delete the list if all elements were trimmmed.
|
||||||
|
func execLTrim(db *DB, args [][]byte) redis.Reply {
|
||||||
|
n := len(args)
|
||||||
|
if n != 3 {
|
||||||
|
return protocol.MakeErrReply(fmt.Sprintf("ERR wrong number of arguments (given %d, expected 3)", n))
|
||||||
|
}
|
||||||
|
key := string(args[0])
|
||||||
|
start, err := strconv.Atoi(string(args[1]))
|
||||||
|
if err != nil {
|
||||||
|
return protocol.MakeErrReply("ERR value is not an integer or out of range")
|
||||||
|
}
|
||||||
|
end, err := strconv.Atoi(string(args[2]))
|
||||||
|
if err != nil {
|
||||||
|
return protocol.MakeErrReply("ERR value is not an integer or out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
// get or init entity
|
||||||
|
list, errReply := db.getAsList(key)
|
||||||
|
if errReply != nil {
|
||||||
|
return errReply
|
||||||
|
}
|
||||||
|
if list == nil {
|
||||||
|
return protocol.MakeOkReply()
|
||||||
|
}
|
||||||
|
|
||||||
|
length := list.Len()
|
||||||
|
if start < 0 {
|
||||||
|
start += length
|
||||||
|
}
|
||||||
|
if end < 0 {
|
||||||
|
end += length
|
||||||
|
}
|
||||||
|
|
||||||
|
leftCount := start
|
||||||
|
rightCount := length - end - 1
|
||||||
|
|
||||||
|
for i := 0; i < leftCount && list.Len() > 0; i++ {
|
||||||
|
list.Remove(0)
|
||||||
|
}
|
||||||
|
for i := 0; i < rightCount && list.Len() > 0; i++ {
|
||||||
|
list.RemoveLast()
|
||||||
|
}
|
||||||
|
|
||||||
|
db.addAof(utils.ToCmdLine3("ltrim", args...))
|
||||||
|
|
||||||
|
return protocol.MakeOkReply()
|
||||||
|
}
|
||||||
|
|
||||||
|
func execLInsert(db *DB, args [][]byte) redis.Reply {
|
||||||
|
n := len(args)
|
||||||
|
if n != 4 {
|
||||||
|
return protocol.MakeErrReply("ERR wrong number of arguments for 'linsert' command")
|
||||||
|
}
|
||||||
|
key := string(args[0])
|
||||||
|
list, errReply := db.getAsList(key)
|
||||||
|
if errReply != nil {
|
||||||
|
return errReply
|
||||||
|
}
|
||||||
|
if list == nil {
|
||||||
|
return protocol.MakeIntReply(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := strings.ToLower(string(args[1]))
|
||||||
|
if dir != "before" && dir != "after" {
|
||||||
|
return protocol.MakeErrReply("ERR syntax error")
|
||||||
|
}
|
||||||
|
|
||||||
|
pivot := string(args[2])
|
||||||
|
index := -1
|
||||||
|
list.ForEach(func(i int, v interface{}) bool {
|
||||||
|
if string(v.([]byte)) == pivot {
|
||||||
|
index = i
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if index == -1 {
|
||||||
|
return protocol.MakeIntReply(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val := args[3]
|
||||||
|
if dir == "before" {
|
||||||
|
list.Insert(index, val)
|
||||||
|
} else {
|
||||||
|
list.Insert(index+1, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
db.addAof(utils.ToCmdLine3("linsert", args...))
|
||||||
|
|
||||||
|
return protocol.MakeIntReply(int64(list.Len()))
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerCommand("LPush", execLPush, writeFirstKey, undoLPush, -3, flagWrite).
|
registerCommand("LPush", execLPush, writeFirstKey, undoLPush, -3, flagWrite).
|
||||||
attachCommandExtra([]string{redisFlagWrite, redisFlagDenyOOM, redisFlagFast}, 1, 1, 1)
|
attachCommandExtra([]string{redisFlagWrite, redisFlagDenyOOM, redisFlagFast}, 1, 1, 1)
|
||||||
@@ -535,4 +630,8 @@ func init() {
|
|||||||
attachCommandExtra([]string{redisFlagWrite, redisFlagDenyOOM}, 1, 1, 1)
|
attachCommandExtra([]string{redisFlagWrite, redisFlagDenyOOM}, 1, 1, 1)
|
||||||
registerCommand("LRange", execLRange, readFirstKey, nil, 4, flagReadOnly).
|
registerCommand("LRange", execLRange, readFirstKey, nil, 4, flagReadOnly).
|
||||||
attachCommandExtra([]string{redisFlagReadonly}, 1, 1, 1)
|
attachCommandExtra([]string{redisFlagReadonly}, 1, 1, 1)
|
||||||
|
registerCommand("LTrim", execLTrim, writeFirstKey, rollbackFirstKey, 4, flagWrite).
|
||||||
|
attachCommandExtra([]string{redisFlagWrite}, 1, 1, 1)
|
||||||
|
registerCommand("LInsert", execLInsert, writeFirstKey, rollbackFirstKey, 5, flagWrite).
|
||||||
|
attachCommandExtra([]string{redisFlagWrite, redisFlagDenyOOM}, 1, 1, 1)
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/hdt3213/godis/lib/utils"
|
"github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/protocol"
|
"github.com/hdt3213/godis/redis/protocol"
|
||||||
"github.com/hdt3213/godis/redis/protocol/asserts"
|
"github.com/hdt3213/godis/redis/protocol/asserts"
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPush(t *testing.T) {
|
func TestPush(t *testing.T) {
|
||||||
@@ -21,7 +21,7 @@ func TestPush(t *testing.T) {
|
|||||||
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.(*protocol.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.Errorf("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"))
|
||||||
@@ -43,7 +43,7 @@ func TestPush(t *testing.T) {
|
|||||||
}
|
}
|
||||||
result := testDB.Exec(nil, utils.ToCmdLine2("rpush", args...))
|
result := testDB.Exec(nil, utils.ToCmdLine2("rpush", args...))
|
||||||
if intResult, _ := result.(*protocol.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.Errorf("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 = protocol.MakeMultiBulkReply(values)
|
expected = protocol.MakeMultiBulkReply(values)
|
||||||
@@ -60,7 +60,7 @@ func TestPush(t *testing.T) {
|
|||||||
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.(*protocol.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.Errorf("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"))
|
||||||
@@ -83,7 +83,7 @@ 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.(*protocol.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.Errorf("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 = protocol.MakeMultiBulkReply(expectedValues)
|
expected = protocol.MakeMultiBulkReply(expectedValues)
|
||||||
@@ -110,7 +110,7 @@ func TestLRange(t *testing.T) {
|
|||||||
actual := testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
actual := testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
||||||
expected := protocol.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.Errorf("range error [%s, %s]", start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
@@ -118,7 +118,7 @@ func TestLRange(t *testing.T) {
|
|||||||
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
||||||
expected = protocol.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.Errorf("range error [%s, %s]", start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
@@ -126,7 +126,7 @@ func TestLRange(t *testing.T) {
|
|||||||
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
||||||
expected = protocol.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.Errorf("range error [%s, %s]", start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
@@ -134,7 +134,7 @@ func TestLRange(t *testing.T) {
|
|||||||
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
||||||
expected = protocol.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.Errorf("range error [%s, %s]", start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = "-10"
|
start = "-10"
|
||||||
@@ -142,7 +142,7 @@ func TestLRange(t *testing.T) {
|
|||||||
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
actual = testDB.Exec(nil, utils.ToCmdLine("lrange", key, start, end))
|
||||||
expected = protocol.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.Errorf("range error [%s, %s]", start, end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,14 +160,14 @@ func TestLIndex(t *testing.T) {
|
|||||||
|
|
||||||
result := testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
result := testDB.Exec(nil, utils.ToCmdLine("llen", key))
|
||||||
if intResult, _ := result.(*protocol.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.Errorf("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 := protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ func TestLIndex(t *testing.T) {
|
|||||||
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, strconv.Itoa(-i)))
|
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key, strconv.Itoa(-i)))
|
||||||
expected := protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,29 +189,29 @@ func TestLRem(t *testing.T) {
|
|||||||
|
|
||||||
result := testDB.Exec(nil, utils.ToCmdLine("lrem", key, "1", "a"))
|
result := testDB.Exec(nil, utils.ToCmdLine("lrem", key, "1", "a"))
|
||||||
if intResult, _ := result.(*protocol.IntReply); intResult.Code != 1 {
|
if intResult, _ := result.(*protocol.IntReply); intResult.Code != 1 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
|
t.Errorf("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.(*protocol.IntReply); intResult.Code != 6 {
|
if intResult, _ := result.(*protocol.IntReply); intResult.Code != 6 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 6, intResult.Code))
|
t.Errorf("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.(*protocol.IntReply); intResult.Code != 2 {
|
if intResult, _ := result.(*protocol.IntReply); intResult.Code != 2 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
t.Errorf("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.(*protocol.IntReply); intResult.Code != 4 {
|
if intResult, _ := result.(*protocol.IntReply); intResult.Code != 4 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 4, intResult.Code))
|
t.Errorf("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.(*protocol.IntReply); intResult.Code != 2 {
|
if intResult, _ := result.(*protocol.IntReply); intResult.Code != 2 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
t.Errorf("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.(*protocol.IntReply); intResult.Code != 2 {
|
if intResult, _ := result.(*protocol.IntReply); intResult.Code != 2 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
t.Errorf("expected %d, actually %d", 2, intResult.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,12 +228,12 @@ func TestLSet(t *testing.T) {
|
|||||||
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.(*protocol.OkReply); !ok {
|
if _, ok := result.(*protocol.OkReply); !ok {
|
||||||
t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes())))
|
t.Errorf("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 := protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// test negative index
|
// test negative index
|
||||||
@@ -241,12 +241,12 @@ func TestLSet(t *testing.T) {
|
|||||||
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.(*protocol.OkReply); !ok {
|
if _, ok := result.(*protocol.OkReply); !ok {
|
||||||
t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes())))
|
t.Errorf("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 := protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,16 +255,16 @@ func TestLSet(t *testing.T) {
|
|||||||
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 := protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
result = testDB.Exec(nil, utils.ToCmdLine("lset", key, strconv.Itoa(len(values)), value))
|
result = testDB.Exec(nil, utils.ToCmdLine("lset", key, strconv.Itoa(len(values)), 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.Errorf("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 = protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,13 +279,13 @@ func TestLPop(t *testing.T) {
|
|||||||
result := testDB.Exec(nil, utils.ToCmdLine("lpop", key))
|
result := testDB.Exec(nil, utils.ToCmdLine("lpop", key))
|
||||||
expected := protocol.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.Errorf("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 := &protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,13 +300,13 @@ func TestRPop(t *testing.T) {
|
|||||||
result := testDB.Exec(nil, utils.ToCmdLine("rpop", key))
|
result := testDB.Exec(nil, utils.ToCmdLine("rpop", key))
|
||||||
expected := protocol.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.Errorf("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 := &protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,17 +322,17 @@ func TestRPopLPush(t *testing.T) {
|
|||||||
result := testDB.Exec(nil, utils.ToCmdLine("rpoplpush", key1, key2))
|
result := testDB.Exec(nil, utils.ToCmdLine("rpoplpush", key1, key2))
|
||||||
expected := protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key2, "0"))
|
result = testDB.Exec(nil, utils.ToCmdLine("lindex", key2, "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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := testDB.Exec(nil, utils.ToCmdLine("rpop", key1))
|
result := testDB.Exec(nil, utils.ToCmdLine("rpop", key1))
|
||||||
expected := &protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +342,7 @@ func TestRPushX(t *testing.T) {
|
|||||||
result := testDB.Exec(nil, utils.ToCmdLine("rpushx", key, "1"))
|
result := testDB.Exec(nil, utils.ToCmdLine("rpushx", key, "1"))
|
||||||
expected := protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
testDB.Exec(nil, utils.ToCmdLine("rpush", key, "1"))
|
testDB.Exec(nil, utils.ToCmdLine("rpush", key, "1"))
|
||||||
@@ -351,12 +351,12 @@ func TestRPushX(t *testing.T) {
|
|||||||
result = testDB.Exec(nil, utils.ToCmdLine("rpushx", key, value))
|
result = testDB.Exec(nil, utils.ToCmdLine("rpushx", key, value))
|
||||||
expected := protocol.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.Errorf("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 := protocol.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.Errorf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -367,7 +367,7 @@ func TestLPushX(t *testing.T) {
|
|||||||
result := testDB.Exec(nil, utils.ToCmdLine("rpushx", key, "1"))
|
result := testDB.Exec(nil, utils.ToCmdLine("rpushx", key, "1"))
|
||||||
expected := protocol.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.Errorf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
testDB.Exec(nil, utils.ToCmdLine("lpush", key, "1"))
|
testDB.Exec(nil, utils.ToCmdLine("lpush", key, "1"))
|
||||||
@@ -376,16 +376,78 @@ func TestLPushX(t *testing.T) {
|
|||||||
result = testDB.Exec(nil, utils.ToCmdLine("lpushx", key, value))
|
result = testDB.Exec(nil, utils.ToCmdLine("lpushx", key, value))
|
||||||
expected := protocol.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.Errorf("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 := protocol.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.Errorf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLTrim(t *testing.T) {
|
||||||
|
testDB.Flush()
|
||||||
|
key := utils.RandString(10)
|
||||||
|
values := []string{"a", "b", "c", "d", "e", "f"}
|
||||||
|
result := testDB.Exec(nil, utils.ToCmdLine("rpush", key, "a", "b", "c", "d", "e", "f"))
|
||||||
|
asserts.AssertIntReply(t, result, 6)
|
||||||
|
|
||||||
|
// case1
|
||||||
|
result1 := testDB.Exec(nil, utils.ToCmdLine("ltrim", key, "1", "-2"))
|
||||||
|
asserts.AssertStatusReply(t, result1, "OK")
|
||||||
|
|
||||||
|
actualValue1 := testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
|
||||||
|
asserts.AssertMultiBulkReply(t, actualValue1, values[1:5])
|
||||||
|
|
||||||
|
// case2
|
||||||
|
result2 := testDB.Exec(nil, utils.ToCmdLine("ltrim", key, "-3", "-2"))
|
||||||
|
asserts.AssertStatusReply(t, result2, "OK")
|
||||||
|
|
||||||
|
actualValue2 := testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
|
||||||
|
asserts.AssertMultiBulkReply(t, actualValue2, values[2:4])
|
||||||
|
|
||||||
|
// case3
|
||||||
|
result3 := testDB.Exec(nil, utils.ToCmdLine("ltrim", key, "1", "0"))
|
||||||
|
asserts.AssertStatusReply(t, result3, "OK")
|
||||||
|
|
||||||
|
actualValue3 := testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
|
||||||
|
asserts.AssertMultiBulkReplySize(t, actualValue3, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLInsert(t *testing.T) {
|
||||||
|
testDB.Flush()
|
||||||
|
key := utils.RandString(10)
|
||||||
|
result := testDB.Exec(nil, utils.ToCmdLine("rpush", key, "a", "b", "c", "d", "e", "f"))
|
||||||
|
asserts.AssertIntReply(t, result, 6)
|
||||||
|
|
||||||
|
// case1
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("linsert", key, "before", "d", "0"))
|
||||||
|
asserts.AssertIntReply(t, result, 7)
|
||||||
|
|
||||||
|
values1 := testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
|
||||||
|
asserts.AssertMultiBulkReply(t, values1, []string{"a", "b", "c", "0", "d", "e", "f"})
|
||||||
|
|
||||||
|
// case2
|
||||||
|
result = testDB.Exec(nil, utils.ToCmdLine("linsert", key, "after", "d", "1"))
|
||||||
|
asserts.AssertIntReply(t, result, 8)
|
||||||
|
|
||||||
|
values2 := testDB.Exec(nil, utils.ToCmdLine("lrange", key, "0", "-1"))
|
||||||
|
asserts.AssertMultiBulkReply(t, values2, []string{"a", "b", "c", "0", "d", "1", "e", "f"})
|
||||||
|
|
||||||
|
// case3
|
||||||
|
result3 := testDB.Exec(nil, utils.ToCmdLine("linsert", key, "test", "d", "1"))
|
||||||
|
asserts.AssertErrReply(t, result3, "ERR syntax error")
|
||||||
|
|
||||||
|
// case4
|
||||||
|
result4 := testDB.Exec(nil, utils.ToCmdLine("linsert", key, "test", "d"))
|
||||||
|
asserts.AssertErrReply(t, result4, "ERR wrong number of arguments for 'linsert' command")
|
||||||
|
|
||||||
|
// case5
|
||||||
|
result5 := testDB.Exec(nil, utils.ToCmdLine("linsert", key, "before", "z", "2"))
|
||||||
|
asserts.AssertIntReply(t, result5, -1)
|
||||||
|
}
|
||||||
|
|
||||||
func TestUndoLPush(t *testing.T) {
|
func TestUndoLPush(t *testing.T) {
|
||||||
testDB.Flush()
|
testDB.Flush()
|
||||||
key := utils.RandString(10)
|
key := utils.RandString(10)
|
||||||
|
Reference in New Issue
Block a user