Skip to content

Commit 778e9d4

Browse files
committed
feat: add type command
1 parent 55fcf15 commit 778e9d4

File tree

3 files changed

+75
-24
lines changed

3 files changed

+75
-24
lines changed

command.go

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
const (
1919
KeepTtl = "KEEPTTL"
2020
Count = "COUNT"
21-
Match = "MATCH"
2221
NX = "NX"
2322
EX = "EX"
2423
PX = "PX"
@@ -45,6 +44,7 @@ var cmdTable = []*Command{
4544
{"set", setCommand, 2, true},
4645
{"get", getCommand, 1, false},
4746
{"del", delCommand, 1, true},
47+
{"type", typeCommand, 1, false},
4848
{"scan", scanCommand, 1, false},
4949
{"incr", incrCommand, 1, true},
5050
{"hset", hsetCommand, 3, true},
@@ -194,6 +194,29 @@ func delCommand(writer *resp.Writer, args []redcon.RESP) {
194194
writer.WriteInt(count)
195195
}
196196

197+
func typeCommand(writer *resp.Writer, args []redcon.RESP) {
198+
key := b2s(args[0].Bytes())
199+
object, ttl := db.dict.Get(key)
200+
if ttl == KeyNotExist {
201+
writer.WriteString("none")
202+
return
203+
}
204+
switch v := object.(type) {
205+
case int, []byte:
206+
writer.WriteString("string")
207+
case *hash.ZipMap:
208+
writer.WriteString("hash")
209+
case *hash.ZipSet, *hash.Set:
210+
writer.WriteString("set")
211+
case *list.QuickList:
212+
writer.WriteString("list")
213+
case *zset.ZipZSet, *zset.ZSet:
214+
writer.WriteString("zset")
215+
default:
216+
writer.WriteError(fmt.Sprintf("unknown type: %T", v))
217+
}
218+
}
219+
197220
func scanCommand(writer *resp.Writer, args []redcon.RESP) {
198221
cursor := int(args[0].Int())
199222
count := 10
@@ -304,11 +327,16 @@ func lpushCommand(writer *resp.Writer, args []redcon.RESP) {
304327
writer.WriteError(err.Error())
305328
return
306329
}
307-
keys := make([]string, 0, len(args)-1)
308-
for _, arg := range args[1:] {
309-
keys = append(keys, b2s(arg.Bytes()))
330+
// fast push
331+
if len(args[1:]) == 1 {
332+
ls.LPush(b2s(args[1].Bytes()))
333+
} else {
334+
keys := make([]string, 0, len(args)-1)
335+
for _, arg := range args[1:] {
336+
keys = append(keys, b2s(arg.Bytes()))
337+
}
338+
ls.LPush(keys...)
310339
}
311-
ls.LPush(keys...)
312340
writer.WriteInt(ls.Len())
313341
}
314342

@@ -319,11 +347,16 @@ func rpushCommand(writer *resp.Writer, args []redcon.RESP) {
319347
writer.WriteError(err.Error())
320348
return
321349
}
322-
keys := make([]string, 0, len(args)-1)
323-
for _, arg := range args[1:] {
324-
keys = append(keys, b2s(arg.Bytes()))
350+
// fast push
351+
if len(args[1:]) == 1 {
352+
ls.RPush(b2s(args[1].Bytes()))
353+
} else {
354+
keys := make([]string, 0, len(args)-1)
355+
for _, arg := range args[1:] {
356+
keys = append(keys, b2s(arg.Bytes()))
357+
}
358+
ls.RPush(keys...)
325359
}
326-
ls.RPush(keys...)
327360
writer.WriteInt(ls.Len())
328361
}
329362

@@ -599,7 +632,6 @@ func fetch[T any](key []byte, new func() T, setnx ...bool) (T, error) {
599632
if !ok {
600633
return v, errWrongType
601634
}
602-
603635
// conversion zipped structure
604636
if len(setnx) > 0 && setnx[0] {
605637
switch data := object.(type) {

command_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
9494
ast.Equal(res, "")
9595
ast.Equal(err, redis.Nil)
9696

97+
_type, _ := rdb.Type(ctx, "foo").Result()
98+
ast.Equal(_type, "string")
99+
100+
_type, _ = rdb.Type(ctx, "not-exist").Result()
101+
ast.Equal(_type, "none")
102+
97103
n, _ := rdb.Del(ctx, "foo", "none").Result()
98104
ast.Equal(n, int64(1))
99105
// setex
@@ -150,6 +156,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
150156
res, _ = rdb.Incr(ctx, "testInt").Result()
151157
ast.Equal(res, int64(2))
152158

159+
_type, _ := rdb.Type(ctx, "testInt").Result()
160+
ast.Equal(_type, "string")
161+
153162
// get int
154163
str, _ := rdb.Get(ctx, "testInt").Result()
155164
ast.Equal(str, "2")
@@ -188,10 +197,16 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
188197
ast.Nil(err)
189198
}
190199

200+
_, err = rdb.HGet(ctx, "map", "not-exist").Result()
201+
ast.Equal(err, redis.Nil)
202+
191203
// hgetall
192204
resm, _ := rdb.HGetAll(ctx, "map").Result()
193205
ast.Equal(len(resm), 100)
194206

207+
_type, _ := rdb.Type(ctx, "map").Result()
208+
ast.Equal(_type, "hash")
209+
195210
// hdel
196211
res, _ = rdb.HDel(ctx, "map", keys[0:10]...).Result()
197212
ast.Equal(res, int64(10))
@@ -228,6 +243,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
228243
n, _ = rdb.RPush(ctx, "list", "4", "5", "6").Result()
229244
ast.Equal(n, int64(6))
230245

246+
_type, _ := rdb.Type(ctx, "list").Result()
247+
ast.Equal(_type, "list")
248+
231249
// list: [1,2,3,4,5,6]
232250
// lrange
233251
res, _ := rdb.LRange(ctx, "list", 0, -1).Result()
@@ -261,6 +279,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
261279
val, _ = rdb.RPop(ctx, "list").Result()
262280
ast.Equal(val, "6")
263281

282+
n, _ = rdb.LPush(ctx, "list", "6").Result()
283+
ast.Equal(n, int64(5))
284+
264285
// pop nil
265286
{
266287
_, err := rdb.LPop(ctx, "list-empty").Result()
@@ -301,6 +322,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
301322
mems, _ := rdb.SMembers(ctx, "set").Result()
302323
ast.ElementsMatch(mems, []string{"k1", "k2", "k3"})
303324

325+
_type, _ := rdb.Type(ctx, "set").Result()
326+
ast.Equal(_type, "set")
327+
304328
// spop
305329
for i := 0; i < 3; i++ {
306330
val, _ := rdb.SPop(ctx, "set").Result()
@@ -324,6 +348,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
324348
_, err = rdb.SRem(ctx, "key", "1").Result()
325349
ast.Equal(err.Error(), errWrongType.Error())
326350

351+
_, err = rdb.SMembers(ctx, "key").Result()
352+
ast.Equal(err.Error(), errWrongType.Error())
353+
327354
_, err = rdb.SPop(ctx, "key").Result()
328355
ast.Equal(err.Error(), errWrongType.Error())
329356
})
@@ -338,6 +365,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
338365
redis.Z{Member: "user3", Score: 100}).Result()
339366
ast.Equal(n, int64(2))
340367

368+
_type, _ := rdb.Type(ctx, "rank").Result()
369+
ast.Equal(_type, "zset")
370+
341371
// zrank
342372
{
343373
res, _ := rdb.ZRank(ctx, "rank", "user1").Result()
@@ -411,6 +441,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
411441
_, err = rdb.ZRank(ctx, "key", "member1").Result()
412442
ast.Equal(err.Error(), errWrongType.Error())
413443

444+
_, err = rdb.ZRange(ctx, "key", 0, -1).Result()
445+
ast.Equal(err.Error(), errWrongType.Error())
446+
414447
_, err = rdb.ZRem(ctx, "key", "member1").Result()
415448
ast.Equal(err.Error(), errWrongType.Error())
416449

const.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@ package main
22

33
import (
44
"github.com/redis/go-redis/v9"
5-
"github.com/xgzlucario/rotom/internal/hash"
6-
"github.com/xgzlucario/rotom/internal/iface"
7-
"github.com/xgzlucario/rotom/internal/list"
8-
"github.com/xgzlucario/rotom/internal/zset"
95
)
106

117
type ObjectType byte
@@ -32,13 +28,3 @@ const (
3228
MB = 1024 * KB
3329
GB = 1024 * MB
3430
)
35-
36-
// type2c is objectType to new encoder.
37-
var type2c = map[ObjectType]func() iface.Encoder{
38-
TypeMap: func() iface.Encoder { return hash.New() },
39-
TypeSet: func() iface.Encoder { return hash.NewSet() },
40-
TypeZipSet: func() iface.Encoder { return hash.NewZipSet() },
41-
TypeList: func() iface.Encoder { return list.New() },
42-
TypeZSet: func() iface.Encoder { return zset.New() },
43-
TypeZipZSet: func() iface.Encoder { return zset.NewZipZSet() },
44-
}

0 commit comments

Comments
 (0)