mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-04 16:32:41 +08:00
refactor command
command
This commit is contained in:
@@ -1,36 +1,67 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"github.com/hdt3213/godis/interface/redis"
|
||||
"github.com/hdt3213/godis/redis/protocol"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var cmdTable = make(map[string]*command)
|
||||
|
||||
type command struct {
|
||||
name string
|
||||
executor ExecFunc
|
||||
prepare PreFunc // return related keys command
|
||||
undo UndoFunc
|
||||
arity int // allow number of args, arity < 0 means len(args) >= -arity
|
||||
flags int
|
||||
// prepare returns related keys command
|
||||
prepare PreFunc
|
||||
// undo generates undo-log before command actually executed, in case the command needs to be rolled back
|
||||
undo UndoFunc
|
||||
// arity means allowed number of cmdArgs, arity < 0 means len(args) >= -arity.
|
||||
// for example: the arity of `get` is 2, `mget` is -2
|
||||
arity int
|
||||
flags int
|
||||
extra *commandExtra
|
||||
}
|
||||
|
||||
type commandExtra struct {
|
||||
signs []string
|
||||
firstKey int
|
||||
lastKey int
|
||||
keyStep int
|
||||
}
|
||||
|
||||
const flagWrite = 0
|
||||
|
||||
const (
|
||||
flagWrite = 0
|
||||
flagReadOnly = 1
|
||||
flagReadOnly = 1 << iota
|
||||
flagSpecial // command invoked in Exec
|
||||
)
|
||||
|
||||
// RegisterCommand registers a new command
|
||||
// arity means allowed number of cmdArgs, arity < 0 means len(args) >= -arity.
|
||||
// for example: the arity of `get` is 2, `mget` is -2
|
||||
func RegisterCommand(name string, executor ExecFunc, prepare PreFunc, rollback UndoFunc, arity int, flags int) {
|
||||
// registerCommand registers a normal command, which only read or modify a limited number of keys
|
||||
func registerCommand(name string, executor ExecFunc, prepare PreFunc, rollback UndoFunc, arity int, flags int) *command {
|
||||
name = strings.ToLower(name)
|
||||
cmdTable[name] = &command{
|
||||
cmd := &command{
|
||||
name: name,
|
||||
executor: executor,
|
||||
prepare: prepare,
|
||||
undo: rollback,
|
||||
arity: arity,
|
||||
flags: flags,
|
||||
}
|
||||
cmdTable[name] = cmd
|
||||
return cmd
|
||||
}
|
||||
|
||||
// registerSpecialCommand registers a special command, such as publish, select, keys, flushAll
|
||||
func registerSpecialCommand(name string, arity int, flags int) *command {
|
||||
name = strings.ToLower(name)
|
||||
flags |= flagSpecial
|
||||
cmd := &command{
|
||||
name: name,
|
||||
arity: arity,
|
||||
flags: flags,
|
||||
}
|
||||
cmdTable[name] = cmd
|
||||
return cmd
|
||||
}
|
||||
|
||||
func isReadOnlyCommand(name string) bool {
|
||||
@@ -41,3 +72,32 @@ func isReadOnlyCommand(name string) bool {
|
||||
}
|
||||
return cmd.flags&flagReadOnly > 0
|
||||
}
|
||||
|
||||
func (cmd *command) toDescReply() redis.Reply {
|
||||
args := make([]redis.Reply, 0, 6)
|
||||
args = append(args,
|
||||
protocol.MakeBulkReply([]byte(cmd.name)),
|
||||
protocol.MakeIntReply(int64(cmd.arity)))
|
||||
if cmd.extra != nil {
|
||||
signs := make([][]byte, len(cmd.extra.signs))
|
||||
for i, v := range cmd.extra.signs {
|
||||
signs[i] = []byte(v)
|
||||
}
|
||||
args = append(args,
|
||||
protocol.MakeMultiBulkReply(signs),
|
||||
protocol.MakeIntReply(int64(cmd.extra.firstKey)),
|
||||
protocol.MakeIntReply(int64(cmd.extra.lastKey)),
|
||||
protocol.MakeIntReply(int64(cmd.extra.keyStep)),
|
||||
)
|
||||
}
|
||||
return protocol.MakeMultiRawReply(args)
|
||||
}
|
||||
|
||||
func (cmd *command) attachCommandExtra(signs []string, firstKey int, lastKey int, keyStep int) {
|
||||
cmd.extra = &commandExtra{
|
||||
signs: signs,
|
||||
firstKey: firstKey,
|
||||
lastKey: lastKey,
|
||||
keyStep: keyStep,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user