forked from mirror/redis
Merge pull request #1068 from go-redis/fix/bit-field-basic
Add basic BITFIELD support
This commit is contained in:
commit
a28bb0bd25
495
command.go
495
command.go
|
@ -274,27 +274,21 @@ func (cmd *Cmd) readReply(rd *proto.Reader) error {
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
// Implements proto.MultiBulkParse
|
||||||
func sliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
func sliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
vals := make([]interface{}, 0, n)
|
vals := make([]interface{}, n)
|
||||||
for i := int64(0); i < n; i++ {
|
for i := 0; i < len(vals); i++ {
|
||||||
v, err := rd.ReadReply(sliceParser)
|
v, err := rd.ReadReply(sliceParser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == Nil {
|
if err == Nil {
|
||||||
vals = append(vals, nil)
|
vals[i] = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err, ok := err.(proto.RedisError); ok {
|
if err, ok := err.(proto.RedisError); ok {
|
||||||
vals = append(vals, err)
|
vals[i] = err
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
vals[i] = v
|
||||||
switch v := v.(type) {
|
|
||||||
case string:
|
|
||||||
vals = append(vals, v)
|
|
||||||
default:
|
|
||||||
vals = append(vals, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return vals, nil
|
return vals, nil
|
||||||
}
|
}
|
||||||
|
@ -405,6 +399,49 @@ func (cmd *IntCmd) readReply(rd *proto.Reader) error {
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type IntSliceCmd struct {
|
||||||
|
baseCmd
|
||||||
|
|
||||||
|
val []int64
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Cmder = (*IntSliceCmd)(nil)
|
||||||
|
|
||||||
|
func NewIntSliceCmd(args ...interface{}) *IntSliceCmd {
|
||||||
|
return &IntSliceCmd{
|
||||||
|
baseCmd: baseCmd{_args: args},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *IntSliceCmd) Val() []int64 {
|
||||||
|
return cmd.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *IntSliceCmd) Result() ([]int64, error) {
|
||||||
|
return cmd.val, cmd.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *IntSliceCmd) String() string {
|
||||||
|
return cmdString(cmd, cmd.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *IntSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
|
cmd.val = make([]int64, n)
|
||||||
|
for i := 0; i < len(cmd.val); i++ {
|
||||||
|
num, err := rd.ReadIntReply()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cmd.val[i] = num
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
type DurationCmd struct {
|
type DurationCmd struct {
|
||||||
baseCmd
|
baseCmd
|
||||||
|
|
||||||
|
@ -479,17 +516,7 @@ func (cmd *TimeCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *TimeCmd) readReply(rd *proto.Reader) error {
|
func (cmd *TimeCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(timeParser)
|
|
||||||
if cmd.err != nil {
|
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.(time.Time)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func timeParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
if n != 2 {
|
if n != 2 {
|
||||||
return nil, fmt.Errorf("got %d elements, expected 2", n)
|
return nil, fmt.Errorf("got %d elements, expected 2", n)
|
||||||
}
|
}
|
||||||
|
@ -504,7 +531,10 @@ func timeParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return time.Unix(sec, microsec*1000), nil
|
cmd.val = time.Unix(sec, microsec*1000)
|
||||||
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -711,29 +741,21 @@ func (cmd *StringSliceCmd) ScanSlice(container interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *StringSliceCmd) readReply(rd *proto.Reader) error {
|
func (cmd *StringSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(stringSliceParser)
|
cmd.val = make([]string, n)
|
||||||
if cmd.err != nil {
|
for i := 0; i < len(cmd.val); i++ {
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.([]string)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func stringSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
ss := make([]string, 0, n)
|
|
||||||
for i := int64(0); i < n; i++ {
|
|
||||||
switch s, err := rd.ReadString(); {
|
switch s, err := rd.ReadString(); {
|
||||||
case err == Nil:
|
case err == Nil:
|
||||||
ss = append(ss, "")
|
cmd.val[i] = ""
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return nil, err
|
return nil, err
|
||||||
default:
|
default:
|
||||||
ss = append(ss, s)
|
cmd.val[i] = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ss, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -765,26 +787,18 @@ func (cmd *BoolSliceCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *BoolSliceCmd) readReply(rd *proto.Reader) error {
|
func (cmd *BoolSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(boolSliceParser)
|
cmd.val = make([]bool, n)
|
||||||
if cmd.err != nil {
|
for i := 0; i < len(cmd.val); i++ {
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.([]bool)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func boolSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
bools := make([]bool, 0, n)
|
|
||||||
for i := int64(0); i < n; i++ {
|
|
||||||
n, err := rd.ReadIntReply()
|
n, err := rd.ReadIntReply()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
bools = append(bools, n == 1)
|
cmd.val[i] = n == 1
|
||||||
}
|
}
|
||||||
return bools, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -816,18 +830,8 @@ func (cmd *StringStringMapCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *StringStringMapCmd) readReply(rd *proto.Reader) error {
|
func (cmd *StringStringMapCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(stringStringMapParser)
|
cmd.val = make(map[string]string, n/2)
|
||||||
if cmd.err != nil {
|
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.(map[string]string)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func stringStringMapParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
m := make(map[string]string, n/2)
|
|
||||||
for i := int64(0); i < n; i += 2 {
|
for i := int64(0); i < n; i += 2 {
|
||||||
key, err := rd.ReadString()
|
key, err := rd.ReadString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -839,9 +843,11 @@ func stringStringMapParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
m[key] = value
|
cmd.val[key] = value
|
||||||
}
|
}
|
||||||
return m, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -873,18 +879,8 @@ func (cmd *StringIntMapCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *StringIntMapCmd) readReply(rd *proto.Reader) error {
|
func (cmd *StringIntMapCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(stringIntMapParser)
|
cmd.val = make(map[string]int64, n/2)
|
||||||
if cmd.err != nil {
|
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.(map[string]int64)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func stringIntMapParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
m := make(map[string]int64, n/2)
|
|
||||||
for i := int64(0); i < n; i += 2 {
|
for i := int64(0); i < n; i += 2 {
|
||||||
key, err := rd.ReadString()
|
key, err := rd.ReadString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -896,9 +892,11 @@ func stringIntMapParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
m[key] = n
|
cmd.val[key] = n
|
||||||
}
|
}
|
||||||
return m, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -930,27 +928,18 @@ func (cmd *StringStructMapCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *StringStructMapCmd) readReply(rd *proto.Reader) error {
|
func (cmd *StringStructMapCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(stringStructMapParser)
|
cmd.val = make(map[string]struct{}, n)
|
||||||
if cmd.err != nil {
|
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.(map[string]struct{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func stringStructMapParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
m := make(map[string]struct{}, n)
|
|
||||||
for i := int64(0); i < n; i++ {
|
for i := int64(0); i < n; i++ {
|
||||||
key, err := rd.ReadString()
|
key, err := rd.ReadString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
cmd.val[key] = struct{}{}
|
||||||
m[key] = struct{}{}
|
|
||||||
}
|
}
|
||||||
return m, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -998,8 +987,8 @@ func (cmd *XMessageSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
// Implements proto.MultiBulkParse
|
||||||
func xMessageSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
func xMessageSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
msgs := make([]XMessage, 0, n)
|
msgs := make([]XMessage, n)
|
||||||
for i := int64(0); i < n; i++ {
|
for i := 0; i < len(msgs); i++ {
|
||||||
_, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
_, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
id, err := rd.ReadString()
|
id, err := rd.ReadString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1011,10 +1000,10 @@ func xMessageSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs = append(msgs, XMessage{
|
msgs[i] = XMessage{
|
||||||
ID: id,
|
ID: id,
|
||||||
Values: v.(map[string]interface{}),
|
Values: v.(map[string]interface{}),
|
||||||
})
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1077,19 +1066,9 @@ func (cmd *XStreamSliceCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *XStreamSliceCmd) readReply(rd *proto.Reader) error {
|
func (cmd *XStreamSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(xStreamSliceParser)
|
cmd.val = make([]XStream, n)
|
||||||
if cmd.err != nil {
|
for i := 0; i < len(cmd.val); i++ {
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.([]XStream)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func xStreamSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
ret := make([]XStream, 0, n)
|
|
||||||
for i := int64(0); i < n; i++ {
|
|
||||||
_, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
_, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
if n != 2 {
|
if n != 2 {
|
||||||
return nil, fmt.Errorf("got %d, wanted 2", n)
|
return nil, fmt.Errorf("got %d, wanted 2", n)
|
||||||
|
@ -1105,17 +1084,19 @@ func xStreamSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, XStream{
|
cmd.val[i] = XStream{
|
||||||
Stream: stream,
|
Stream: stream,
|
||||||
Messages: v.([]XMessage),
|
Messages: v.([]XMessage),
|
||||||
})
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -1153,16 +1134,7 @@ func (cmd *XPendingCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *XPendingCmd) readReply(rd *proto.Reader) error {
|
func (cmd *XPendingCmd) readReply(rd *proto.Reader) error {
|
||||||
var info interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
info, cmd.err = rd.ReadArrayReply(xPendingParser)
|
|
||||||
if cmd.err != nil {
|
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = info.(*XPending)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func xPendingParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
if n != 4 {
|
if n != 4 {
|
||||||
return nil, fmt.Errorf("got %d, wanted 4", n)
|
return nil, fmt.Errorf("got %d, wanted 4", n)
|
||||||
}
|
}
|
||||||
|
@ -1182,7 +1154,7 @@ func xPendingParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pending := &XPending{
|
cmd.val = &XPending{
|
||||||
Count: count,
|
Count: count,
|
||||||
Lower: lower,
|
Lower: lower,
|
||||||
Higher: higher,
|
Higher: higher,
|
||||||
|
@ -1204,10 +1176,10 @@ func xPendingParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if pending.Consumers == nil {
|
if cmd.val.Consumers == nil {
|
||||||
pending.Consumers = make(map[string]int64)
|
cmd.val.Consumers = make(map[string]int64)
|
||||||
}
|
}
|
||||||
pending.Consumers[consumerName] = consumerPending
|
cmd.val.Consumers[consumerName] = consumerPending
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
|
@ -1221,7 +1193,9 @@ func xPendingParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return pending, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -1259,17 +1233,8 @@ func (cmd *XPendingExtCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *XPendingExtCmd) readReply(rd *proto.Reader) error {
|
func (cmd *XPendingExtCmd) readReply(rd *proto.Reader) error {
|
||||||
var info interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
info, cmd.err = rd.ReadArrayReply(xPendingExtSliceParser)
|
cmd.val = make([]XPendingExt, 0, n)
|
||||||
if cmd.err != nil {
|
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = info.([]XPendingExt)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func xPendingExtSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
ret := make([]XPendingExt, 0, n)
|
|
||||||
for i := int64(0); i < n; i++ {
|
for i := int64(0); i < n; i++ {
|
||||||
_, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
_, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
if n != 4 {
|
if n != 4 {
|
||||||
|
@ -1296,7 +1261,7 @@ func xPendingExtSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, XPendingExt{
|
cmd.val = append(cmd.val, XPendingExt{
|
||||||
ID: id,
|
ID: id,
|
||||||
Consumer: consumer,
|
Consumer: consumer,
|
||||||
Idle: time.Duration(idle) * time.Millisecond,
|
Idle: time.Duration(idle) * time.Millisecond,
|
||||||
|
@ -1308,13 +1273,13 @@ func xPendingExtSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type ZSliceCmd struct {
|
type ZSliceCmd struct {
|
||||||
baseCmd
|
baseCmd
|
||||||
|
|
||||||
|
@ -1342,34 +1307,27 @@ func (cmd *ZSliceCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *ZSliceCmd) readReply(rd *proto.Reader) error {
|
func (cmd *ZSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(zSliceParser)
|
cmd.val = make([]Z, n/2)
|
||||||
if cmd.err != nil {
|
for i := 0; i < len(cmd.val); i++ {
|
||||||
|
member, err := rd.ReadString()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
score, err := rd.ReadFloatReply()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.val[i] = Z{
|
||||||
|
Member: member,
|
||||||
|
Score: score,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
})
|
||||||
return cmd.err
|
return cmd.err
|
||||||
}
|
|
||||||
cmd.val = v.([]Z)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func zSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
zz := make([]Z, n/2)
|
|
||||||
for i := int64(0); i < n; i += 2 {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
z := &zz[i/2]
|
|
||||||
|
|
||||||
z.Member, err = rd.ReadString()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
z.Score, err = rd.ReadFloatReply()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return zz, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -1401,38 +1359,32 @@ func (cmd *ZWithKeyCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *ZWithKeyCmd) readReply(rd *proto.Reader) error {
|
func (cmd *ZWithKeyCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(zWithKeyParser)
|
|
||||||
if cmd.err != nil {
|
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.(*ZWithKey)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func zWithKeyParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
if n != 3 {
|
if n != 3 {
|
||||||
return nil, fmt.Errorf("got %d elements, expected 3", n)
|
return nil, fmt.Errorf("got %d elements, expected 3", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
var z ZWithKey
|
cmd.val = &ZWithKey{}
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
z.Key, err = rd.ReadString()
|
cmd.val.Key, err = rd.ReadString()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
z.Member, err = rd.ReadString()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
z.Score, err = rd.ReadFloatReply()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &z, nil
|
cmd.val.Member, err = rd.ReadString()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.val.Score, err = rd.ReadFloatReply()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -1519,19 +1471,9 @@ func (cmd *ClusterSlotsCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error {
|
func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(clusterSlotsParser)
|
cmd.val = make([]ClusterSlot, n)
|
||||||
if cmd.err != nil {
|
for i := 0; i < len(cmd.val); i++ {
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.([]ClusterSlot)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func clusterSlotsParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
slots := make([]ClusterSlot, n)
|
|
||||||
for i := 0; i < len(slots); i++ {
|
|
||||||
n, err := rd.ReadArrayLen()
|
n, err := rd.ReadArrayLen()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1583,13 +1525,15 @@ func clusterSlotsParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
slots[i] = ClusterSlot{
|
cmd.val[i] = ClusterSlot{
|
||||||
Start: int(start),
|
Start: int(start),
|
||||||
End: int(end),
|
End: int(end),
|
||||||
Nodes: nodes,
|
Nodes: nodes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return slots, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -1683,6 +1627,29 @@ func (cmd *GeoLocationCmd) readReply(rd *proto.Reader) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newGeoLocationSliceParser(q *GeoRadiusQuery) proto.MultiBulkParse {
|
||||||
|
return func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
|
locs := make([]GeoLocation, 0, n)
|
||||||
|
for i := int64(0); i < n; i++ {
|
||||||
|
v, err := rd.ReadReply(newGeoLocationParser(q))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch vv := v.(type) {
|
||||||
|
case string:
|
||||||
|
locs = append(locs, GeoLocation{
|
||||||
|
Name: vv,
|
||||||
|
})
|
||||||
|
case *GeoLocation:
|
||||||
|
locs = append(locs, *vv)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("got %T, expected string or *GeoLocation", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return locs, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse {
|
func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse {
|
||||||
return func(rd *proto.Reader, n int64) (interface{}, error) {
|
return func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
var loc GeoLocation
|
var loc GeoLocation
|
||||||
|
@ -1727,29 +1694,6 @@ func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGeoLocationSliceParser(q *GeoRadiusQuery) proto.MultiBulkParse {
|
|
||||||
return func(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
locs := make([]GeoLocation, 0, n)
|
|
||||||
for i := int64(0); i < n; i++ {
|
|
||||||
v, err := rd.ReadReply(newGeoLocationParser(q))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch vv := v.(type) {
|
|
||||||
case string:
|
|
||||||
locs = append(locs, GeoLocation{
|
|
||||||
Name: vv,
|
|
||||||
})
|
|
||||||
case *GeoLocation:
|
|
||||||
locs = append(locs, *vv)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("got %T, expected string or *GeoLocation", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return locs, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
type GeoPos struct {
|
type GeoPos struct {
|
||||||
|
@ -1759,7 +1703,7 @@ type GeoPos struct {
|
||||||
type GeoPosCmd struct {
|
type GeoPosCmd struct {
|
||||||
baseCmd
|
baseCmd
|
||||||
|
|
||||||
positions []*GeoPos
|
val []*GeoPos
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Cmder = (*GeoPosCmd)(nil)
|
var _ Cmder = (*GeoPosCmd)(nil)
|
||||||
|
@ -1771,7 +1715,7 @@ func NewGeoPosCmd(args ...interface{}) *GeoPosCmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *GeoPosCmd) Val() []*GeoPos {
|
func (cmd *GeoPosCmd) Val() []*GeoPos {
|
||||||
return cmd.positions
|
return cmd.val
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *GeoPosCmd) Result() ([]*GeoPos, error) {
|
func (cmd *GeoPosCmd) Result() ([]*GeoPos, error) {
|
||||||
|
@ -1779,48 +1723,42 @@ func (cmd *GeoPosCmd) Result() ([]*GeoPos, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *GeoPosCmd) String() string {
|
func (cmd *GeoPosCmd) String() string {
|
||||||
return cmdString(cmd, cmd.positions)
|
return cmdString(cmd, cmd.val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *GeoPosCmd) readReply(rd *proto.Reader) error {
|
func (cmd *GeoPosCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(geoPosSliceParser)
|
cmd.val = make([]*GeoPos, n)
|
||||||
if cmd.err != nil {
|
for i := 0; i < len(cmd.val); i++ {
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.positions = v.([]*GeoPos)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func geoPosSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
positions := make([]*GeoPos, 0, n)
|
|
||||||
for i := int64(0); i < n; i++ {
|
|
||||||
_, err := rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
_, err := rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
var pos GeoPos
|
longitude, err := rd.ReadFloatReply()
|
||||||
var err error
|
|
||||||
|
|
||||||
pos.Longitude, err = rd.ReadFloatReply()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.Latitude, err = rd.ReadFloatReply()
|
latitude, err := rd.ReadFloatReply()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
positions = append(positions, &pos)
|
cmd.val[i] = &GeoPos{
|
||||||
|
Longitude: longitude,
|
||||||
|
Latitude: latitude,
|
||||||
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == Nil {
|
if err == Nil {
|
||||||
positions = append(positions, nil)
|
cmd.val[i] = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return positions, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -1862,38 +1800,29 @@ func (cmd *CommandsInfoCmd) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error {
|
func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error {
|
||||||
var v interface{}
|
_, cmd.err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
v, cmd.err = rd.ReadArrayReply(commandInfoSliceParser)
|
cmd.val = make(map[string]*CommandInfo, n)
|
||||||
if cmd.err != nil {
|
|
||||||
return cmd.err
|
|
||||||
}
|
|
||||||
cmd.val = v.(map[string]*CommandInfo)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements proto.MultiBulkParse
|
|
||||||
func commandInfoSliceParser(rd *proto.Reader, n int64) (interface{}, error) {
|
|
||||||
m := make(map[string]*CommandInfo, n)
|
|
||||||
for i := int64(0); i < n; i++ {
|
for i := int64(0); i < n; i++ {
|
||||||
v, err := rd.ReadReply(commandInfoParser)
|
v, err := rd.ReadReply(commandInfoParser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
vv := v.(*CommandInfo)
|
vv := v.(*CommandInfo)
|
||||||
m[vv.Name] = vv
|
cmd.val[vv.Name] = vv
|
||||||
|
|
||||||
}
|
}
|
||||||
return m, nil
|
return nil, nil
|
||||||
|
})
|
||||||
|
return cmd.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func commandInfoParser(rd *proto.Reader, n int64) (interface{}, error) {
|
func commandInfoParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
var cmd CommandInfo
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if n != 6 {
|
if n != 6 {
|
||||||
return nil, fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 6", n)
|
return nil, fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 6", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cmd CommandInfo
|
||||||
|
var err error
|
||||||
|
|
||||||
cmd.Name, err = rd.ReadString()
|
cmd.Name, err = rd.ReadString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1905,11 +1834,23 @@ func commandInfoParser(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
}
|
}
|
||||||
cmd.Arity = int8(arity)
|
cmd.Arity = int8(arity)
|
||||||
|
|
||||||
flags, err := rd.ReadReply(stringSliceParser)
|
_, err = rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) {
|
||||||
|
cmd.Flags = make([]string, n)
|
||||||
|
for i := 0; i < len(cmd.Flags); i++ {
|
||||||
|
switch s, err := rd.ReadString(); {
|
||||||
|
case err == Nil:
|
||||||
|
cmd.Flags[i] = ""
|
||||||
|
case err != nil:
|
||||||
|
return nil, err
|
||||||
|
default:
|
||||||
|
cmd.Flags[i] = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd.Flags = flags.([]string)
|
|
||||||
|
|
||||||
firstKeyPos, err := rd.ReadIntReply()
|
firstKeyPos, err := rd.ReadIntReply()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
11
commands.go
11
commands.go
|
@ -98,6 +98,7 @@ type Cmdable interface {
|
||||||
BitOpXor(destKey string, keys ...string) *IntCmd
|
BitOpXor(destKey string, keys ...string) *IntCmd
|
||||||
BitOpNot(destKey string, key string) *IntCmd
|
BitOpNot(destKey string, key string) *IntCmd
|
||||||
BitPos(key string, bit int64, pos ...int64) *IntCmd
|
BitPos(key string, bit int64, pos ...int64) *IntCmd
|
||||||
|
BitField(key string, args ...interface{}) *IntSliceCmd
|
||||||
Decr(key string) *IntCmd
|
Decr(key string) *IntCmd
|
||||||
DecrBy(key string, decrement int64) *IntCmd
|
DecrBy(key string, decrement int64) *IntCmd
|
||||||
Get(key string) *StringCmd
|
Get(key string) *StringCmd
|
||||||
|
@ -724,6 +725,16 @@ func (c cmdable) BitPos(key string, bit int64, pos ...int64) *IntCmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c cmdable) BitField(key string, args ...interface{}) *IntSliceCmd {
|
||||||
|
a := make([]interface{}, 0, 2+len(args))
|
||||||
|
a = append(a, "bitfield")
|
||||||
|
a = append(a, key)
|
||||||
|
a = append(a, args...)
|
||||||
|
cmd := NewIntSliceCmd(a...)
|
||||||
|
c(cmd)
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
func (c cmdable) Decr(key string) *IntCmd {
|
func (c cmdable) Decr(key string) *IntCmd {
|
||||||
cmd := NewIntCmd("decr", key)
|
cmd := NewIntCmd("decr", key)
|
||||||
c(cmd)
|
c(cmd)
|
||||||
|
|
|
@ -968,6 +968,12 @@ var _ = Describe("Commands", func() {
|
||||||
Expect(pos).To(Equal(int64(-1)))
|
Expect(pos).To(Equal(int64(-1)))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("should BitField", func() {
|
||||||
|
nn, err := client.BitField("mykey", "INCRBY", "i5", 100, 1, "GET", "u4", 0).Result()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(nn).To(Equal([]int64{1, 0}))
|
||||||
|
})
|
||||||
|
|
||||||
It("should Decr", func() {
|
It("should Decr", func() {
|
||||||
set := client.Set("key", "10", 0)
|
set := client.Set("key", "10", 0)
|
||||||
Expect(set.Err()).NotTo(HaveOccurred())
|
Expect(set.Err()).NotTo(HaveOccurred())
|
||||||
|
|
Loading…
Reference in New Issue