diff --git a/v2/README.md b/v2/README.md index fc3fe41..de82188 100644 --- a/v2/README.md +++ b/v2/README.md @@ -21,6 +21,11 @@ Install: go get github.com/vmihailenco/redis/v2 +Updgrading from previous version +-------------------------------- + +Type system should catch most changes. But you have manually change `SetEx`, `PSetEx`, `Expire` and `PExpire` to use `time.Duration` instead of `int64`. + Getting started --------------- diff --git a/v2/command.go b/v2/command.go index cf434af..47b8115 100644 --- a/v2/command.go +++ b/v2/command.go @@ -156,6 +156,39 @@ func (cmd *IntCmd) Val() int64 { //------------------------------------------------------------------------------ +type DurationCmd struct { + *baseCmd + precision time.Duration +} + +func NewDurationCmd(precision time.Duration, args ...string) *DurationCmd { + return &DurationCmd{ + baseCmd: newBaseCmd(args...), + precision: precision, + } +} + +func (cmd *DurationCmd) parseReply(rd reader) (interface{}, error) { + v, err := parseReply(rd) + if err != nil { + return 0, err + } + vv := time.Duration(v.(int64)) + if vv == -1 { + return vv, nil + } + return vv * cmd.precision, nil +} + +func (cmd *DurationCmd) Val() time.Duration { + if cmd.val == nil { + return 0 + } + return cmd.val.(time.Duration) +} + +//------------------------------------------------------------------------------ + type BoolCmd struct { *baseCmd } diff --git a/v2/commands.go b/v2/commands.go index 0026bff..ef666dd 100644 --- a/v2/commands.go +++ b/v2/commands.go @@ -67,14 +67,14 @@ func (c *Client) Exists(key string) *BoolCmd { return req } -func (c *Client) Expire(key string, seconds int64) *BoolCmd { - req := NewBoolCmd("EXPIRE", key, strconv.FormatInt(seconds, 10)) +func (c *Client) Expire(key string, dur time.Duration) *BoolCmd { + req := NewBoolCmd("EXPIRE", key, strconv.FormatInt(int64(dur/time.Second), 10)) c.Process(req) return req } -func (c *Client) ExpireAt(key string, timestamp int64) *BoolCmd { - req := NewBoolCmd("EXPIREAT", key, strconv.FormatInt(timestamp, 10)) +func (c *Client) ExpireAt(key string, tm time.Time) *BoolCmd { + req := NewBoolCmd("EXPIREAT", key, strconv.FormatInt(tm.Unix(), 10)) c.Process(req) return req } @@ -119,9 +119,9 @@ func (c *Client) ObjectEncoding(keys ...string) *StringCmd { return req } -func (c *Client) ObjectIdleTime(keys ...string) *IntCmd { +func (c *Client) ObjectIdleTime(keys ...string) *DurationCmd { args := append([]string{"OBJECT", "IDLETIME"}, keys...) - req := NewIntCmd(args...) + req := NewDurationCmd(time.Second, args...) c.Process(req) return req } @@ -132,20 +132,24 @@ func (c *Client) Persist(key string) *BoolCmd { return req } -func (c *Client) PExpire(key string, milliseconds int64) *BoolCmd { - req := NewBoolCmd("PEXPIRE", key, strconv.FormatInt(milliseconds, 10)) +func (c *Client) PExpire(key string, dur time.Duration) *BoolCmd { + req := NewBoolCmd("PEXPIRE", key, strconv.FormatInt(int64(dur/time.Millisecond), 10)) c.Process(req) return req } -func (c *Client) PExpireAt(key string, milliseconds int64) *BoolCmd { - req := NewBoolCmd("PEXPIREAT", key, strconv.FormatInt(milliseconds, 10)) +func (c *Client) PExpireAt(key string, tm time.Time) *BoolCmd { + req := NewBoolCmd( + "PEXPIREAT", + key, + strconv.FormatInt(tm.UnixNano()/int64(time.Millisecond), 10), + ) c.Process(req) return req } -func (c *Client) PTTL(key string) *IntCmd { - req := NewIntCmd("PTTL", key) +func (c *Client) PTTL(key string) *DurationCmd { + req := NewDurationCmd(time.Millisecond, "PTTL", key) c.Process(req) return req } @@ -213,8 +217,8 @@ func (c *Client) Sort(key string, sort Sort) *StringSliceCmd { return req } -func (c *Client) TTL(key string) *IntCmd { - req := NewIntCmd("TTL", key) +func (c *Client) TTL(key string) *DurationCmd { + req := NewDurationCmd(time.Second, "TTL", key) c.Process(req) return req } @@ -355,11 +359,11 @@ func (c *Client) MSetNX(pairs ...string) *BoolCmd { return req } -func (c *Client) PSetEx(key string, milliseconds int64, value string) *StatusCmd { +func (c *Client) PSetEx(key string, dur time.Duration, value string) *StatusCmd { req := NewStatusCmd( "PSETEX", key, - strconv.FormatInt(milliseconds, 10), + strconv.FormatInt(int64(dur/time.Millisecond), 10), value, ) c.Process(req) @@ -383,8 +387,8 @@ func (c *Client) SetBit(key string, offset int64, value int) *IntCmd { return req } -func (c *Client) SetEx(key string, seconds int64, value string) *StatusCmd { - req := NewStatusCmd("SETEX", key, strconv.FormatInt(seconds, 10), value) +func (c *Client) SetEx(key string, dur time.Duration, value string) *StatusCmd { + req := NewStatusCmd("SETEX", key, strconv.FormatInt(int64(dur/time.Second), 10), value) c.Process(req) return req } @@ -1066,10 +1070,6 @@ func (c *Client) LastSave() *IntCmd { return req } -func (c *Client) Monitor() { - panic("not implemented") -} - func (c *Client) Save() *StatusCmd { req := NewStatusCmd("SAVE") c.Process(req) diff --git a/v2/redis_test.go b/v2/redis_test.go index baebff2..207f122 100644 --- a/v2/redis_test.go +++ b/v2/redis_test.go @@ -431,13 +431,13 @@ func (t *RedisTest) TestCmdKeysExpire(c *C) { c.Assert(set.Err(), IsNil) c.Assert(set.Val(), Equals, "OK") - expire := t.client.Expire("key", 10) + expire := t.client.Expire("key", 10*time.Second) c.Assert(expire.Err(), IsNil) c.Assert(expire.Val(), Equals, true) ttl := t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Equals, int64(10)) + c.Assert(ttl.Val(), Equals, 10*time.Second) set = t.client.Set("key", "Hello World") c.Assert(set.Err(), IsNil) @@ -445,7 +445,7 @@ func (t *RedisTest) TestCmdKeysExpire(c *C) { ttl = t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Equals, int64(-1)) + c.Assert(ttl.Val(), Equals, time.Duration(-1)) } func (t *RedisTest) TestCmdKeysExpireAt(c *C) { @@ -457,7 +457,7 @@ func (t *RedisTest) TestCmdKeysExpireAt(c *C) { c.Assert(exists.Err(), IsNil) c.Assert(exists.Val(), Equals, true) - expireAt := t.client.ExpireAt("key", 1293840000) + expireAt := t.client.ExpireAt("key", time.Now().Add(-time.Hour)) c.Assert(expireAt.Err(), IsNil) c.Assert(expireAt.Val(), Equals, true) @@ -543,7 +543,7 @@ func (t *RedisTest) TestCmdKeysObject(c *C) { idleTime := t.client.ObjectIdleTime("key") c.Assert(idleTime.Err(), IsNil) - c.Assert(idleTime.Val(), Equals, int64(0)) + c.Assert(idleTime.Val(), Equals, time.Duration(0)) } func (t *RedisTest) TestCmdKeysPersist(c *C) { @@ -551,13 +551,13 @@ func (t *RedisTest) TestCmdKeysPersist(c *C) { c.Assert(set.Err(), IsNil) c.Assert(set.Val(), Equals, "OK") - expire := t.client.Expire("key", 10) + expire := t.client.Expire("key", 10*time.Second) c.Assert(expire.Err(), IsNil) c.Assert(expire.Val(), Equals, true) ttl := t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Equals, int64(10)) + c.Assert(ttl.Val(), Equals, 10*time.Second) persist := t.client.Persist("key") c.Assert(persist.Err(), IsNil) @@ -565,7 +565,7 @@ func (t *RedisTest) TestCmdKeysPersist(c *C) { ttl = t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Equals, int64(-1)) + c.Assert(ttl.Val(), Equals, time.Duration(-1)) } func (t *RedisTest) TestCmdKeysPExpire(c *C) { @@ -573,17 +573,17 @@ func (t *RedisTest) TestCmdKeysPExpire(c *C) { c.Assert(set.Err(), IsNil) c.Assert(set.Val(), Equals, "OK") - pexpire := t.client.PExpire("key", 1900) + pexpire := t.client.PExpire("key", 900*time.Millisecond) c.Assert(pexpire.Err(), IsNil) c.Assert(pexpire.Val(), Equals, true) ttl := t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Equals, int64(2)) + c.Assert(ttl.Val(), Equals, time.Second) pttl := t.client.PTTL("key") c.Assert(pttl.Err(), IsNil) - c.Assert(pttl.Val() > 1800 && pttl.Val() <= 1900, Equals, true) + c.Assert(pttl.Val(), Equals, 900*time.Millisecond) } func (t *RedisTest) TestCmdKeysPExpireAt(c *C) { @@ -591,17 +591,17 @@ func (t *RedisTest) TestCmdKeysPExpireAt(c *C) { c.Assert(set.Err(), IsNil) c.Assert(set.Val(), Equals, "OK") - pExpireAt := t.client.PExpireAt("key", 1555555555005) + pExpireAt := t.client.PExpireAt("key", time.Now().Add(900*time.Millisecond)) c.Assert(pExpireAt.Err(), IsNil) c.Assert(pExpireAt.Val(), Equals, true) ttl := t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Not(Equals), int64(0)) + c.Assert(ttl.Val(), Equals, time.Second) pttl := t.client.PTTL("key") c.Assert(pttl.Err(), IsNil) - c.Assert(pttl.Val(), Not(Equals), int64(0)) + c.Assert(pttl.Val(), Equals, 900*time.Millisecond) } func (t *RedisTest) TestCmdKeysPTTL(c *C) { @@ -609,13 +609,13 @@ func (t *RedisTest) TestCmdKeysPTTL(c *C) { c.Assert(set.Err(), IsNil) c.Assert(set.Val(), Equals, "OK") - expire := t.client.Expire("key", 1) + expire := t.client.Expire("key", time.Second) c.Assert(expire.Err(), IsNil) c.Assert(set.Val(), Equals, "OK") pttl := t.client.PTTL("key") c.Assert(pttl.Err(), IsNil) - c.Assert(pttl.Val() > 900 && pttl.Val() <= 1000, Equals, true) + c.Assert(pttl.Val(), Equals, time.Second) } func (t *RedisTest) TestCmdKeysRandomKey(c *C) { @@ -703,19 +703,19 @@ func (t *RedisTest) TestCmdKeysSort(c *C) { func (t *RedisTest) TestCmdKeysTTL(c *C) { ttl := t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Equals, int64(-1)) + c.Assert(ttl.Val(), Equals, time.Duration(-1)) set := t.client.Set("key", "hello") c.Assert(set.Err(), IsNil) c.Assert(set.Val(), Equals, "OK") - expire := t.client.Expire("key", 60) + expire := t.client.Expire("key", 60*time.Second) c.Assert(expire.Err(), IsNil) c.Assert(expire.Val(), Equals, true) ttl = t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Equals, int64(60)) + c.Assert(ttl.Val(), Equals, 60*time.Second) } func (t *RedisTest) TestCmdKeysType(c *C) { @@ -999,13 +999,13 @@ func (t *RedisTest) TestStringsMSetNX(c *C) { } func (t *RedisTest) TestStringsPSetEx(c *C) { - pSetEx := t.client.PSetEx("key", 1000, "hello") + pSetEx := t.client.PSetEx("key", 50*time.Millisecond, "hello") c.Assert(pSetEx.Err(), IsNil) c.Assert(pSetEx.Val(), Equals, "OK") pttl := t.client.PTTL("key") c.Assert(pttl.Err(), IsNil) - c.Assert(pttl.Val() > 900 && pttl.Val() <= 1000, Equals, true) + c.Assert(pttl.Val(), Equals, 50*time.Millisecond) get := t.client.Get("key") c.Assert(get.Err(), IsNil) @@ -1023,13 +1023,13 @@ func (t *RedisTest) TestStringsSetGet(c *C) { } func (t *RedisTest) TestStringsSetEx(c *C) { - setEx := t.client.SetEx("key", 10, "hello") + setEx := t.client.SetEx("key", 10*time.Second, "hello") c.Assert(setEx.Err(), IsNil) c.Assert(setEx.Val(), Equals, "OK") ttl := t.client.TTL("key") c.Assert(ttl.Err(), IsNil) - c.Assert(ttl.Val(), Equals, int64(10)) + c.Assert(ttl.Val(), Equals, 10*time.Second) } func (t *RedisTest) TestStringsSetNX(c *C) {