-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand.go
More file actions
109 lines (101 loc) · 2.48 KB
/
command.go
File metadata and controls
109 lines (101 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package main
import "fmt"
var cmdTable []GodisCommand = []GodisCommand{
GodisCommand{name: "get", proc: getCommand, arity: 2},
GodisCommand{name: "set", proc: setCommand, arity: 3},
GodisCommand{name: "expire", proc: expireCommand, arity: 3},
GodisCommand{name: "lpush", proc: lpushCommand, arity: 3},
GodisCommand{name: "lpop", proc: lpopCommand, arity: 2},
// todo: other commands
}
func getCommand(c *GodisClient) {
key := c.args[1]
val := findKeyRead(key)
if val == nil {
c.AddReplyStr("$-1\r\n")
} else if val.Type_ != GSTR {
c.AddReplyStr("-ERR: wrong type\r\n")
} else {
str := val.StrVal()
c.AddReplyStr(fmt.Sprintf("$%d%v\r\n", len(str), str))
}
}
func setCommand(c *GodisClient) {
key := c.args[1]
val := c.args[2]
if val.Type_ != GSTR {
c.AddReplyStr("-ERR: wrong type\r\n")
}
// checkout key-val type is correct or not
entry := server.db.data.Find(key)
if entry != nil && entry.Val.Type_ != GSTR {
c.AddReplyStr(fmt.Sprintf("%v\r\n", WO_ERR.Error()))
return
}
// set key-val pair
server.db.data.Set(key, val)
server.db.expire.Delete(key)
c.AddReplyStr("+OK\r\n")
}
func expireCommand(c *GodisClient) {
key := c.args[1]
val := c.args[2]
// todo : extract same code, use methods like aop
if val.Type_ != GSTR {
c.AddReplyStr("-ERR: wrong type\r\n")
}
expire := GetMsTime() + (val.IntVal() * 1000)
expObj := CreateFromInt(expire)
server.db.expire.Set(key, expObj)
expObj.DecrRefCount()
c.AddReplyStr("+OK\r\n")
}
func lpushCommand(c *GodisClient) {
key := c.args[1]
val := c.args[2]
if val.Type_ != GSTR {
c.AddReplyStr("-ERR: wrong type\r\n")
}
err := lPush(server.db.data, key, val)
if err != nil {
c.AddReplyStr(fmt.Sprintf("%v\r\n", err.Error()))
return
}
server.db.expire.Delete(key)
c.AddReplyStr("+OK\r\n")
}
func lPush(dict *Dict, key *Gobj, val *Gobj) error {
entry := dict.Find(key)
if entry != nil {
if entry.Val.Type_ != GLIST {
return WO_ERR
}
ls := entry.Val.Val_.(*List)
ls.LPush(val)
val.IncrRefCount()
return nil
}
entry = dict.AddRaw(key)
ls := ListCreate(ListType{EqualFunc: GStrEqual})
entry.Val = CreateObject(GLIST, ls)
ls.LPush(val)
val.IncrRefCount()
return nil
}
func lpopCommand(c *GodisClient) {
key := c.args[1]
// checkout key either exists
val := findKeyRead(key)
if val == nil {
c.AddReplyStr("$-1\r\n")
return
}
ls := val.Val_.(*List)
node := ls.LPop()
if node == nil {
c.AddReplyStr("$-1\r\n")
return
}
str := node.StrVal()
c.AddReplyStr(fmt.Sprintf("$%d%v\r\n", len(str), str))
}