func checkslotsmgrt(t *testing.T, r *bufio.Reader, w *bufio.Writer, c chan error, expect ...interface{}) { if len(expect) != 0 { req1, err := redis.Decode(r) checkerror(t, err, true) cmd1, args1, err := redis.ParseArgs(req1) checkerror(t, err, cmd1 == "select" && len(args1) == 1) checkerror(t, redis.Encode(w, redis.NewString("OK")), true) checkerror(t, w.Flush(), true) req2, err := redis.Decode(r) cmd2, args2, err := redis.ParseArgs(req2) checkerror(t, err, cmd2 == "slotsrestore" && len(args2) == len(expect)) m := make(map[string]*struct { key, value string ttlms uint64 }) for i := 0; i < len(expect)/3; i++ { v := &struct { key, value string ttlms uint64 }{key: expect[i*3].(string), value: expect[i*3+2].(string)} v.ttlms, err = ParseUint(expect[i*3+1]) checkerror(t, err, true) m[v.key] = v } for i := 0; i < len(expect)/3; i++ { key := args2[i*3] ttlms := args2[i*3+1] value := args2[i*3+2] v := m[string(key)] checkerror(t, nil, v != nil) checkerror(t, nil, string(key) == v.key) b, err := rdb.DecodeDump(value) checkerror(t, err, string(b.(rdb.String)) == v.value) x, err := strconv.Atoi(string(ttlms)) checkerror(t, err, true) if v.ttlms == 0 { checkerror(t, nil, x == 0) } else { checkerror(t, nil, x != 0) checkerror(t, nil, math.Abs(float64(x)-float64(v.ttlms)) < 500) } } checkerror(t, redis.Encode(w, redis.NewString("OK")), true) checkerror(t, w.Flush(), true) } select { case err := <-c: checkerror(t, err, true) case <-time.After(time.Second): checkerror(t, nil, false) } }
// CONFIG get key / set key value func (h *Handler) Config(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 2 && len(args) != 3 { return toRespErrorf("len(args) = %d, expect = 2 or 3", len(args)) } _, err := session(arg0, args) if err != nil { return toRespError(err) } sub, args := strings.ToLower(string(args[0])), args[1:] switch sub { default: return toRespErrorf("unknown sub-command = %s", sub) case "get": if len(args) != 2 { return toRespErrorf("len(args) = %d, expect = 2", len(args)) } switch e := strings.ToLower(string(args[1])); e { default: return toRespErrorf("unknown entry %s", e) case "maxmemory": return redis.NewString("0"), nil } } }
// BGSAVETO path func (h *Handler) BgsaveTo(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 1 { return toRespErrorf("len(args) = %d, expect = 1", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } bg := h.counters.bgsave.Add(1) defer h.counters.bgsave.Sub(1) if bg != 1 { return toRespErrorf("bgsave is busy: %d, should be 1", bg) } sp, err := s.Rpdb().NewSnapshot() if err != nil { return toRespError(err) } defer s.Rpdb().ReleaseSnapshot(sp) if err := h.bgsaveTo(sp, string(args[0])); err != nil { return toRespError(err) } else { return redis.NewString("OK"), nil } }
// SLAVEOF host port func (h *Handler) SlaveOf(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 2 { return toRespErrorf("len(args) = %d, expect = 2", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } addr := fmt.Sprintf("%s:%s", string(args[0]), string(args[1])) log.Infof("set slave of %s", addr) var c *conn if strings.ToLower(addr) != "no:one" { if nc, err := net.DialTimeout("tcp", addr, time.Second); err != nil { return toRespError(errors.Trace(err)) } else { c = newConn(nc, s.Rpdb(), 0) if err := c.ping(); err != nil { c.Close() return toRespError(err) } } } select { case <-h.signal: if c != nil { c.Close() } return toRespErrorf("sync master has been closed") case h.master <- c: return redis.NewString("OK"), nil } }
// ECHO text func (h *Handler) Echo(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 1 { return toRespErrorf("len(args) = %d, expect = 1", len(args)) } _, err := session(arg0, args) if err != nil { return toRespError(err) } return redis.NewString(string(args[0])), nil }
// SLOTSRESTORE key ttlms value [key ttlms value ...] func (h *Handler) SlotsRestore(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) == 0 || len(args)%3 != 0 { return toRespErrorf("len(args) = %d, expect != 0 && mod 3 == 0", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } if err := s.Rpdb().SlotsRestore(s.DB(), iconvert(args)...); err != nil { return toRespError(err) } else { return redis.NewString("OK"), nil } }
// HMSET key field value [field value ...] func (h *Handler) HMSet(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) == 1 || len(args)%2 != 1 { return toRespErrorf("len(args) = %d, expect != 1 && mod 2 = 1", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } if err := s.Rpdb().HMSet(s.DB(), iconvert(args)...); err != nil { return toRespError(err) } else { return redis.NewString("OK"), nil } }
// HINCRBYFLOAT key field delta func (h *Handler) HIncrByFloat(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 3 { return toRespErrorf("len(args) = %d, expect = 3", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } if v, err := s.Rpdb().HIncrByFloat(s.DB(), iconvert(args)...); err != nil { return toRespError(err) } else { return redis.NewString(rpdb.FormatFloatString(v)), nil } }
// COMPACTALL func (h *Handler) CompactAll(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 0 { return toRespErrorf("len(args) = %d, expect = 0", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } if err := s.Rpdb().CompactAll(); err != nil { return toRespError(err) } else { return redis.NewString("OK"), nil } }
// LTRIM key beg end func (h *Handler) LTrim(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 3 { return toRespErrorf("len(args) = %d, expect = 3", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } if err := s.Rpdb().LTrim(s.DB(), iconvert(args)...); err != nil { return toRespError(err) } else { return redis.NewString("OK"), nil } }
// TYPE key func (h *Handler) Type(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 1 { return toRespErrorf("len(args) = %d, expect = 1", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } if c, err := s.Rpdb().Type(s.DB(), iconvert(args)...); err != nil { return toRespError(err) } else { return redis.NewString(c.String()), nil } }
// ZSCORE key member func (h *Handler) ZScore(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 2 { return toRespErrorf("len(args) = %d, expect = 2", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } if v, ok, err := s.Rpdb().ZScore(s.DB(), iconvert(args)...); err != nil { return toRespError(err) } else if !ok { return redis.NewBulkBytes(nil), nil } else { return redis.NewString(rpdb.FormatFloatString(v)), nil } }
// SELECT db func (h *Handler) Select(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 1 { return toRespErrorf("len(args) = %d, expect = 1", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } if db, err := rpdb.ParseUint(args[0]); err != nil { return toRespError(err) } else if db > math.MaxUint32 { return toRespErrorf("parse db = %d", db) } else { s.SetDB(uint32(db)) return redis.NewString("OK"), nil } }
// INFO func (h *Handler) Info(arg0 interface{}, args [][]byte) (redis.Resp, error) { if len(args) != 0 { return toRespErrorf("len(args) = %d, expect = 0", len(args)) } s, err := session(arg0, args) if err != nil { return toRespError(err) } var b bytes.Buffer if v, err := s.Rpdb().Info(); err != nil { return toRespError(err) } else { fmt.Fprintf(&b, "# Database\n") fmt.Fprintf(&b, "%s\n", v) fmt.Fprintf(&b, "\n") fmt.Fprintf(&b, "# Config\n") fmt.Fprintf(&b, "%s\n", h.config) fmt.Fprintf(&b, "\n") fmt.Fprintf(&b, "# Clients\n") fmt.Fprintf(&b, "syncto:%s\n", h.syncto) fmt.Fprintf(&b, "bgsave:%d\n", h.counters.bgsave.Get()) fmt.Fprintf(&b, "clients:%d\n", h.counters.clients.Get()) fmt.Fprintf(&b, "clients_accepted:%d\n", h.counters.clientsAccepted.Get()) fmt.Fprintf(&b, "commands:%d\n", h.counters.commands.Get()) fmt.Fprintf(&b, "commands_failed:%d\n", h.counters.commandsFailed.Get()) fmt.Fprintf(&b, "sync_rdb_remains:%d\n", h.counters.syncRdbRemains.Get()) fmt.Fprintf(&b, "sync_total_bytes:%d\n", h.counters.syncTotalBytes.Get()) fmt.Fprintf(&b, "sync_cache_bytes:%d\n", h.counters.syncCacheBytes.Get()) fmt.Fprintf(&b, "\n") return redis.NewString(b.String()), nil } }