// MSET func (m *Miniredis) cmdMset(out *redeo.Responder, r *redeo.Request) error { if len(r.Args) < 2 { setDirty(r.Client()) return r.WrongNumberOfArgs() } if !m.handleAuth(r.Client(), out) { return nil } if len(r.Args)%2 != 0 { setDirty(r.Client()) // non-default error message out.WriteErrorString("ERR wrong number of arguments for MSET") return nil } return withTx(m, out, r, func(out *redeo.Responder, ctx *connCtx) { db := m.db(ctx.selectedDB) for len(r.Args) > 0 { key := r.Args[0] value := r.Args[1] r.Args = r.Args[2:] db.del(key, true) // clear TTL db.stringSet(key, value) } out.WriteOK() }) }
// MSETNX func (m *Miniredis) cmdMsetnx(out *redeo.Responder, r *redeo.Request) error { if len(r.Args) < 2 { setDirty(r.Client()) return r.WrongNumberOfArgs() } if !m.handleAuth(r.Client(), out) { return nil } if len(r.Args)%2 != 0 { setDirty(r.Client()) // non-default error message (yes, with 'MSET'). out.WriteErrorString("ERR wrong number of arguments for MSET") return nil } return withTx(m, out, r, func(out *redeo.Responder, ctx *connCtx) { db := m.db(ctx.selectedDB) keys := map[string]string{} existing := false for len(r.Args) > 0 { key := r.Args[0] value := r.Args[1] r.Args = r.Args[2:] keys[key] = value if _, ok := db.keys[key]; ok { existing = true } } res := 0 if !existing { res = 1 for k, v := range keys { // Nothing to delete. That's the whole point. db.stringSet(k, v) } } out.WriteInt(res) }) }
// SET func (m *Miniredis) cmdSet(out *redeo.Responder, r *redeo.Request) error { if len(r.Args) < 2 { setDirty(r.Client()) return r.WrongNumberOfArgs() } if !m.handleAuth(r.Client(), out) { return nil } var ( nx = false // set iff not exists xx = false // set iff exists expire = 0 // For seconds and milliseconds. ) key := r.Args[0] value := r.Args[1] r.Args = r.Args[2:] for len(r.Args) > 0 { switch strings.ToUpper(r.Args[0]) { case "NX": nx = true r.Args = r.Args[1:] continue case "XX": xx = true r.Args = r.Args[1:] continue case "EX", "PX": if len(r.Args) < 2 { setDirty(r.Client()) out.WriteErrorString(msgInvalidInt) return nil } var err error expire, err = strconv.Atoi(r.Args[1]) if err != nil { setDirty(r.Client()) out.WriteErrorString(msgInvalidInt) return nil } r.Args = r.Args[2:] continue default: setDirty(r.Client()) out.WriteErrorString(msgSyntaxError) return nil } } return withTx(m, out, r, func(out *redeo.Responder, ctx *connCtx) { db := m.db(ctx.selectedDB) if nx { if db.exists(key) { out.WriteNil() return } } if xx { if !db.exists(key) { out.WriteNil() return } } db.del(key, true) // be sure to remove existing values of other type keys. // a vanilla SET clears the expire db.stringSet(key, value) if expire != 0 { db.expire[key] = expire } out.WriteOK() }) }