ADD EXPIRETIME and EXPIRETIME command

This commit is contained in:
li
2023-02-14 14:23:40 +08:00
committed by finley
parent 85ce68768a
commit d77f08c140
3 changed files with 92 additions and 0 deletions

View File

@@ -16,8 +16,10 @@ func makeRouter() map[string]CmdFunc {
routerMap["expire"] = defaultFunc routerMap["expire"] = defaultFunc
routerMap["expireat"] = defaultFunc routerMap["expireat"] = defaultFunc
routerMap["expiretime"] = defaultFunc
routerMap["pexpire"] = defaultFunc routerMap["pexpire"] = defaultFunc
routerMap["pexpireat"] = defaultFunc routerMap["pexpireat"] = defaultFunc
routerMap["pexpiretime"] = defaultFunc
routerMap["ttl"] = defaultFunc routerMap["ttl"] = defaultFunc
routerMap["pttl"] = defaultFunc routerMap["pttl"] = defaultFunc
routerMap["persist"] = defaultFunc routerMap["persist"] = defaultFunc

View File

@@ -185,6 +185,23 @@ func execExpireAt(db *DB, args [][]byte) redis.Reply {
return protocol.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execExpireTime returns the absolute Unix expiration timestamp in seconds at which the given key will expire.
func execExpireTime(db *DB, args [][]byte) redis.Reply {
key := string(args[0])
_, exists := db.GetEntity(key)
if !exists {
return protocol.MakeIntReply(-2)
}
raw, exists := db.ttlMap.Get(key)
if !exists {
return protocol.MakeIntReply(-1)
}
rawExpireTime, _ := raw.(time.Time)
expireTime := rawExpireTime.Unix()
return protocol.MakeIntReply(expireTime)
}
// execPExpire sets a key's time to live in milliseconds // execPExpire sets a key's time to live in milliseconds
func execPExpire(db *DB, args [][]byte) redis.Reply { func execPExpire(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
@@ -227,6 +244,23 @@ func execPExpireAt(db *DB, args [][]byte) redis.Reply {
return protocol.MakeIntReply(1) return protocol.MakeIntReply(1)
} }
// execPExpireTime returns the absolute Unix expiration timestamp in milliseconds at which the given key will expire.
func execPExpireTime(db *DB, args [][]byte) redis.Reply {
key := string(args[0])
_, exists := db.GetEntity(key)
if !exists {
return protocol.MakeIntReply(-2)
}
raw, exists := db.ttlMap.Get(key)
if !exists {
return protocol.MakeIntReply(-1)
}
rawExpireTime, _ := raw.(time.Time)
expireTime := rawExpireTime.UnixMilli()
return protocol.MakeIntReply(expireTime)
}
// execTTL returns a key's time to live in seconds // execTTL returns a key's time to live in seconds
func execTTL(db *DB, args [][]byte) redis.Reply { func execTTL(db *DB, args [][]byte) redis.Reply {
key := string(args[0]) key := string(args[0])
@@ -379,8 +413,10 @@ func init() {
RegisterCommand("Del", execDel, writeAllKeys, undoDel, -2, flagWrite) RegisterCommand("Del", execDel, writeAllKeys, undoDel, -2, flagWrite)
RegisterCommand("Expire", execExpire, writeFirstKey, undoExpire, 3, flagWrite) RegisterCommand("Expire", execExpire, writeFirstKey, undoExpire, 3, flagWrite)
RegisterCommand("ExpireAt", execExpireAt, writeFirstKey, undoExpire, 3, flagWrite) RegisterCommand("ExpireAt", execExpireAt, writeFirstKey, undoExpire, 3, flagWrite)
RegisterCommand("ExpireTime", execExpireTime, readFirstKey, nil, 2, flagReadOnly)
RegisterCommand("PExpire", execPExpire, writeFirstKey, undoExpire, 3, flagWrite) RegisterCommand("PExpire", execPExpire, writeFirstKey, undoExpire, 3, flagWrite)
RegisterCommand("PExpireAt", execPExpireAt, writeFirstKey, undoExpire, 3, flagWrite) RegisterCommand("PExpireAt", execPExpireAt, writeFirstKey, undoExpire, 3, flagWrite)
RegisterCommand("PExpireTime", execPExpireTime, readFirstKey, nil, 2, flagReadOnly)
RegisterCommand("TTL", execTTL, readFirstKey, nil, 2, flagReadOnly) RegisterCommand("TTL", execTTL, readFirstKey, nil, 2, flagReadOnly)
RegisterCommand("PTTL", execPTTL, readFirstKey, nil, 2, flagReadOnly) RegisterCommand("PTTL", execPTTL, readFirstKey, nil, 2, flagReadOnly)
RegisterCommand("Persist", execPersist, writeFirstKey, undoExpire, 2, flagWrite) RegisterCommand("Persist", execPersist, writeFirstKey, undoExpire, 2, flagWrite)

View File

@@ -191,6 +191,60 @@ func TestExpireAt(t *testing.T) {
} }
} }
func TestExpiredTime(t *testing.T) {
//测试ExpireTime
testDB.Flush()
key := utils.RandString(10)
value := utils.RandString(10)
testDB.Exec(nil, utils.ToCmdLine("set", key, value))
result := testDB.Exec(nil, utils.ToCmdLine("ttl", key))
asserts.AssertIntReply(t, result, -1)
result = testDB.Exec(nil, utils.ToCmdLine("EXPIRETIME", key))
asserts.AssertIntReply(t, result, -1)
result = testDB.Exec(nil, utils.ToCmdLine("PEXPIRETIME", key))
asserts.AssertIntReply(t, result, -1)
testDB.Exec(nil, utils.ToCmdLine("EXPIRE", key, "2"))
//tt := time.Now()
result = testDB.Exec(nil, utils.ToCmdLine("ttl", key))
asserts.AssertIntReply(t, result, 2)
result = testDB.Exec(nil, utils.ToCmdLine("EXPIRETIME", key))
asserts.AssertIntReply(t, result, int(time.Now().Add(2*time.Second).Unix()))
intResult, ok := result.(*protocol.IntReply)
if !ok {
t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return
}
if intResult.Code <= 0 {
t.Errorf("expected ttl more than 0, actual: %d", intResult.Code)
return
}
result = testDB.Exec(nil, utils.ToCmdLine("PEXPIRETIME", key))
asserts.AssertIntReply(t, result, int(time.Now().Add(2*time.Second).UnixMilli()))
intResult, ok = result.(*protocol.IntReply)
if !ok {
t.Error(fmt.Sprintf("expected int protocol, actually %s", result.ToBytes()))
return
}
if intResult.Code <= 0 {
t.Errorf("expected ttl more than 0, actual: %d", intResult.Code)
return
}
time.Sleep(3 * time.Second)
result = testDB.Exec(nil, utils.ToCmdLine("ttl", key))
asserts.AssertIntReply(t, result, -2)
result = testDB.Exec(nil, utils.ToCmdLine("EXPIRETIME", key))
asserts.AssertIntReply(t, result, -2)
intResult, ok = result.(*protocol.IntReply)
result = testDB.Exec(nil, utils.ToCmdLine("PEXPIRETIME", key))
asserts.AssertIntReply(t, result, -2)
intResult, ok = result.(*protocol.IntReply)
}
func TestKeys(t *testing.T) { func TestKeys(t *testing.T) {
testDB.Flush() testDB.Flush()
key := utils.RandString(10) key := utils.RandString(10)