package redis import ( "context" "time" ) type GenericCmdable interface { Del(ctx context.Context, keys ...string) *IntCmd Dump(ctx context.Context, key string) *StringCmd Exists(ctx context.Context, keys ...string) *IntCmd Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd ExpireTime(ctx context.Context, key string) *DurationCmd ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd Keys(ctx context.Context, pattern string) *StringSliceCmd Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd Move(ctx context.Context, key string, db int) *BoolCmd ObjectRefCount(ctx context.Context, key string) *IntCmd ObjectEncoding(ctx context.Context, key string) *StringCmd ObjectIdleTime(ctx context.Context, key string) *DurationCmd Persist(ctx context.Context, key string) *BoolCmd PExpire(ctx context.Context, key string, expiration time.Duration) *BoolCmd PExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd PExpireTime(ctx context.Context, key string) *DurationCmd PTTL(ctx context.Context, key string) *DurationCmd RandomKey(ctx context.Context) *StringCmd Rename(ctx context.Context, key, newkey string) *StatusCmd RenameNX(ctx context.Context, key, newkey string) *BoolCmd Restore(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd RestoreReplace(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd Sort(ctx context.Context, key string, sort *Sort) *StringSliceCmd SortRO(ctx context.Context, key string, sort *Sort) *StringSliceCmd SortStore(ctx context.Context, key, store string, sort *Sort) *IntCmd SortInterfaces(ctx context.Context, key string, sort *Sort) *SliceCmd Touch(ctx context.Context, keys ...string) *IntCmd TTL(ctx context.Context, key string) *DurationCmd Type(ctx context.Context, key string) *StatusCmd Copy(ctx context.Context, sourceKey string, destKey string, db int, replace bool) *IntCmd Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd } func (c cmdable) Del(ctx context.Context, keys ...string) *IntCmd { args := make([]interface{}, 1+len(keys)) args[0] = "del" for i, key := range keys { args[1+i] = key } cmd := NewIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } func (c cmdable) Unlink(ctx context.Context, keys ...string) *IntCmd { args := make([]interface{}, 1+len(keys)) args[0] = "unlink" for i, key := range keys { args[1+i] = key } cmd := NewIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } func (c cmdable) Dump(ctx context.Context, key string) *StringCmd { cmd := NewStringCmd(ctx, "dump", key) _ = c(ctx, cmd) return cmd } func (c cmdable) Exists(ctx context.Context, keys ...string) *IntCmd { args := make([]interface{}, 1+len(keys)) args[0] = "exists" for i, key := range keys { args[1+i] = key } cmd := NewIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } func (c cmdable) Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd { return c.expire(ctx, key, expiration, "") } func (c cmdable) ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd { return c.expire(ctx, key, expiration, "NX") } func (c cmdable) ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd { return c.expire(ctx, key, expiration, "XX") } func (c cmdable) ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd { return c.expire(ctx, key, expiration, "GT") } func (c cmdable) ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd { return c.expire(ctx, key, expiration, "LT") } func (c cmdable) expire( ctx context.Context, key string, expiration time.Duration, mode string, ) *BoolCmd { args := make([]interface{}, 3, 4) args[0] = "expire" args[1] = key args[2] = formatSec(ctx, expiration) if mode != "" { args = append(args, mode) } cmd := NewBoolCmd(ctx, args...) _ = c(ctx, cmd) return cmd } func (c cmdable) ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd { cmd := NewBoolCmd(ctx, "expireat", key, tm.Unix()) _ = c(ctx, cmd) return cmd } func (c cmdable) ExpireTime(ctx context.Context, key string) *DurationCmd { cmd := NewDurationCmd(ctx, time.Second, "expiretime", key) _ = c(ctx, cmd) return cmd } func (c cmdable) Keys(ctx context.Context, pattern string) *StringSliceCmd { cmd := NewStringSliceCmd(ctx, "keys", pattern) _ = c(ctx, cmd) return cmd } func (c cmdable) Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd { cmd := NewStatusCmd( ctx, "migrate", host, port, key, db, formatMs(ctx, timeout), ) cmd.setReadTimeout(timeout) _ = c(ctx, cmd) return cmd } func (c cmdable) Move(ctx context.Context, key string, db int) *BoolCmd { cmd := NewBoolCmd(ctx, "move", key, db) _ = c(ctx, cmd) return cmd } func (c cmdable) ObjectRefCount(ctx context.Context, key string) *IntCmd { cmd := NewIntCmd(ctx, "object", "refcount", key) _ = c(ctx, cmd) return cmd } func (c cmdable) ObjectEncoding(ctx context.Context, key string) *StringCmd { cmd := NewStringCmd(ctx, "object", "encoding", key) _ = c(ctx, cmd) return cmd } func (c cmdable) ObjectIdleTime(ctx context.Context, key string) *DurationCmd { cmd := NewDurationCmd(ctx, time.Second, "object", "idletime", key) _ = c(ctx, cmd) return cmd } func (c cmdable) Persist(ctx context.Context, key string) *BoolCmd { cmd := NewBoolCmd(ctx, "persist", key) _ = c(ctx, cmd) return cmd } func (c cmdable) PExpire(ctx context.Context, key string, expiration time.Duration) *BoolCmd { cmd := NewBoolCmd(ctx, "pexpire", key, formatMs(ctx, expiration)) _ = c(ctx, cmd) return cmd } func (c cmdable) PExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd { cmd := NewBoolCmd( ctx, "pexpireat", key, tm.UnixNano()/int64(time.Millisecond), ) _ = c(ctx, cmd) return cmd } func (c cmdable) PExpireTime(ctx context.Context, key string) *DurationCmd { cmd := NewDurationCmd(ctx, time.Millisecond, "pexpiretime", key) _ = c(ctx, cmd) return cmd } func (c cmdable) PTTL(ctx context.Context, key string) *DurationCmd { cmd := NewDurationCmd(ctx, time.Millisecond, "pttl", key) _ = c(ctx, cmd) return cmd } func (c cmdable) RandomKey(ctx context.Context) *StringCmd { cmd := NewStringCmd(ctx, "randomkey") _ = c(ctx, cmd) return cmd } func (c cmdable) Rename(ctx context.Context, key, newkey string) *StatusCmd { cmd := NewStatusCmd(ctx, "rename", key, newkey) _ = c(ctx, cmd) return cmd } func (c cmdable) RenameNX(ctx context.Context, key, newkey string) *BoolCmd { cmd := NewBoolCmd(ctx, "renamenx", key, newkey) _ = c(ctx, cmd) return cmd } func (c cmdable) Restore(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd { cmd := NewStatusCmd( ctx, "restore", key, formatMs(ctx, ttl), value, ) _ = c(ctx, cmd) return cmd } func (c cmdable) RestoreReplace(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd { cmd := NewStatusCmd( ctx, "restore", key, formatMs(ctx, ttl), value, "replace", ) _ = c(ctx, cmd) return cmd } type Sort struct { By string Offset, Count int64 Get []string Order string Alpha bool } func (sort *Sort) args(command, key string) []interface{} { args := []interface{}{command, key} if sort.By != "" { args = append(args, "by", sort.By) } if sort.Offset != 0 || sort.Count != 0 { args = append(args, "limit", sort.Offset, sort.Count) } for _, get := range sort.Get { args = append(args, "get", get) } if sort.Order != "" { args = append(args, sort.Order) } if sort.Alpha { args = append(args, "alpha") } return args } func (c cmdable) SortRO(ctx context.Context, key string, sort *Sort) *StringSliceCmd { cmd := NewStringSliceCmd(ctx, sort.args("sort_ro", key)...) _ = c(ctx, cmd) return cmd } func (c cmdable) Sort(ctx context.Context, key string, sort *Sort) *StringSliceCmd { cmd := NewStringSliceCmd(ctx, sort.args("sort", key)...) _ = c(ctx, cmd) return cmd } func (c cmdable) SortStore(ctx context.Context, key, store string, sort *Sort) *IntCmd { args := sort.args("sort", key) if store != "" { args = append(args, "store", store) } cmd := NewIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } func (c cmdable) SortInterfaces(ctx context.Context, key string, sort *Sort) *SliceCmd { cmd := NewSliceCmd(ctx, sort.args("sort", key)...) _ = c(ctx, cmd) return cmd } func (c cmdable) Touch(ctx context.Context, keys ...string) *IntCmd { args := make([]interface{}, len(keys)+1) args[0] = "touch" for i, key := range keys { args[i+1] = key } cmd := NewIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } func (c cmdable) TTL(ctx context.Context, key string) *DurationCmd { cmd := NewDurationCmd(ctx, time.Second, "ttl", key) _ = c(ctx, cmd) return cmd } func (c cmdable) Type(ctx context.Context, key string) *StatusCmd { cmd := NewStatusCmd(ctx, "type", key) _ = c(ctx, cmd) return cmd } func (c cmdable) Copy(ctx context.Context, sourceKey, destKey string, db int, replace bool) *IntCmd { args := []interface{}{"copy", sourceKey, destKey, "DB", db} if replace { args = append(args, "REPLACE") } cmd := NewIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } //------------------------------------------------------------------------------ func (c cmdable) Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd { args := []interface{}{"scan", cursor} if match != "" { args = append(args, "match", match) } if count > 0 { args = append(args, "count", count) } cmd := NewScanCmd(ctx, c, args...) _ = c(ctx, cmd) return cmd } func (c cmdable) ScanType(ctx context.Context, cursor uint64, match string, count int64, keyType string) *ScanCmd { args := []interface{}{"scan", cursor} if match != "" { args = append(args, "match", match) } if count > 0 { args = append(args, "count", count) } if keyType != "" { args = append(args, "type", keyType) } cmd := NewScanCmd(ctx, c, args...) _ = c(ctx, cmd) return cmd }