mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-05 08:46:56 +08:00
Feat:Add "copy" command
Add "copy" command,also fixes the out of range error of select when the number is negative. Move execCopy to "keys.go" , Add test in "keys_test.go", Add "copy.go" and "copy_test.go" file.
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/hdt3213/godis/lib/wildcard"
|
||||
"github.com/hdt3213/godis/redis/protocol"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -308,6 +309,68 @@ func undoExpire(db *DB, args [][]byte) []CmdLine {
|
||||
}
|
||||
}
|
||||
|
||||
// execCopy usage: COPY source destination [DB destination-db] [REPLACE]
|
||||
// This command copies the value stored at the source key to the destination key.
|
||||
func execCopy(mdb *MultiDB, conn redis.Connection, args [][]byte) redis.Reply {
|
||||
dbIndex := conn.GetDBIndex()
|
||||
db := mdb.dbSet[dbIndex] // Current DB
|
||||
replaceFlag := false
|
||||
srcKey := string(args[0])
|
||||
destKey := string(args[1])
|
||||
|
||||
// Parse options
|
||||
if len(args) > 2 {
|
||||
for i := 2; i < len(args); i++ {
|
||||
arg := strings.ToLower(string(args[i]))
|
||||
if arg == "db" {
|
||||
if i+1 >= len(args) {
|
||||
return &protocol.SyntaxErrReply{}
|
||||
}
|
||||
idx, err := strconv.Atoi(string(args[i+1]))
|
||||
if err != nil {
|
||||
return &protocol.SyntaxErrReply{}
|
||||
}
|
||||
if idx >= len(mdb.dbSet) || idx < 0 {
|
||||
return protocol.MakeErrReply("ERR DB index is out of range")
|
||||
}
|
||||
dbIndex = idx
|
||||
i++
|
||||
} else if arg == "replace" {
|
||||
replaceFlag = true
|
||||
} else {
|
||||
return &protocol.SyntaxErrReply{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if srcKey == destKey && dbIndex == conn.GetDBIndex() {
|
||||
return protocol.MakeErrReply("ERR source and destination objects are the same")
|
||||
}
|
||||
|
||||
// source key does not exist
|
||||
src, exists := db.GetEntity(srcKey)
|
||||
if !exists {
|
||||
return protocol.MakeIntReply(0)
|
||||
}
|
||||
|
||||
destDB := mdb.dbSet[dbIndex]
|
||||
if _, exists = destDB.GetEntity(destKey); exists != false {
|
||||
// If destKey exists and there is no "replace" option
|
||||
if replaceFlag == false {
|
||||
return protocol.MakeIntReply(0)
|
||||
}
|
||||
}
|
||||
|
||||
destDB.PutEntity(destKey, src)
|
||||
raw, exists := db.ttlMap.Get(srcKey)
|
||||
if exists {
|
||||
expire := raw.(time.Time)
|
||||
destDB.Expire(destKey, expire)
|
||||
}
|
||||
mdb.aofHandler.AddAof(conn.GetDBIndex(), utils.ToCmdLine3("copy", args...))
|
||||
return protocol.MakeIntReply(1)
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterCommand("Del", execDel, writeAllKeys, undoDel, -2)
|
||||
RegisterCommand("Expire", execExpire, writeFirstKey, undoExpire, 3)
|
||||
|
Reference in New Issue
Block a user