mirror of https://github.com/tidwall/tile38.git
Better RENAME/RENAMENX tests
This commit is contained in:
parent
ede1ce0269
commit
960c860b3a
|
@ -244,10 +244,11 @@ func (s *Server) cmdGET(msg *Message) (resp.Value, error) {
|
|||
if i > 0 {
|
||||
buf.WriteString(`,`)
|
||||
}
|
||||
buf.WriteString(jsonString(f.Name()) + ":" + f.Value().JSON())
|
||||
buf.WriteString(jsonString(f.Name()) + ":" +
|
||||
f.Value().JSON())
|
||||
} else {
|
||||
fvals = append(fvals,
|
||||
resp.StringValue(f.Name()), resp.StringValue(f.Value().Data()))
|
||||
fvals = append(fvals, resp.StringValue(f.Name()),
|
||||
resp.StringValue(f.Value().Data()))
|
||||
}
|
||||
i++
|
||||
return true
|
||||
|
@ -441,7 +442,8 @@ func (s *Server) cmdDROP(msg *Message) (resp.Value, commandDetails, error) {
|
|||
d.timestamp = time.Now()
|
||||
switch msg.OutputType {
|
||||
case JSON:
|
||||
res = resp.StringValue(`{"ok":true,"elapsed":"` + time.Since(start).String() + "\"}")
|
||||
res = resp.StringValue(`{"ok":true,"elapsed":"` +
|
||||
time.Since(start).String() + "\"}")
|
||||
case RESP:
|
||||
if d.updated {
|
||||
res = resp.IntegerValue(1)
|
||||
|
@ -452,54 +454,67 @@ func (s *Server) cmdDROP(msg *Message) (resp.Value, commandDetails, error) {
|
|||
return res, d, nil
|
||||
}
|
||||
|
||||
func (s *Server) cmdRename(msg *Message) (res resp.Value, d commandDetails, err error) {
|
||||
nx := msg.Command() == "renamenx"
|
||||
// RENAME key newkey
|
||||
// RENAMENX key newkey
|
||||
func (s *Server) cmdRENAME(msg *Message) (resp.Value, commandDetails, error) {
|
||||
start := time.Now()
|
||||
vs := msg.Args[1:]
|
||||
var ok bool
|
||||
if vs, d.key, ok = tokenval(vs); !ok || d.key == "" {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
|
||||
// >> Args
|
||||
|
||||
args := msg.Args
|
||||
if len(args) != 3 {
|
||||
return retwerr(errInvalidNumberOfArguments)
|
||||
}
|
||||
if vs, d.newKey, ok = tokenval(vs); !ok || d.newKey == "" {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
if len(vs) != 0 {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
col, _ := s.cols.Get(d.key)
|
||||
nx := strings.ToLower(args[0]) == "renamenx"
|
||||
key := args[1]
|
||||
newKey := args[2]
|
||||
|
||||
// >> Operation
|
||||
|
||||
col, _ := s.cols.Get(key)
|
||||
if col == nil {
|
||||
err = errKeyNotFound
|
||||
return
|
||||
return retwerr(errKeyNotFound)
|
||||
}
|
||||
var ierr error
|
||||
s.hooks.Ascend(nil, func(v interface{}) bool {
|
||||
h := v.(*Hook)
|
||||
if h.Key == d.key || h.Key == d.newKey {
|
||||
err = errKeyHasHooksSet
|
||||
if h.Key == key || h.Key == newKey {
|
||||
ierr = errKeyHasHooksSet
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
d.command = "rename"
|
||||
newCol, _ := s.cols.Get(d.newKey)
|
||||
if ierr != nil {
|
||||
return retwerr(ierr)
|
||||
}
|
||||
var updated bool
|
||||
newCol, _ := s.cols.Get(newKey)
|
||||
if newCol == nil {
|
||||
d.updated = true
|
||||
} else if nx {
|
||||
d.updated = false
|
||||
} else {
|
||||
s.cols.Delete(d.newKey)
|
||||
d.updated = true
|
||||
updated = true
|
||||
} else if !nx {
|
||||
s.cols.Delete(newKey)
|
||||
updated = true
|
||||
}
|
||||
if d.updated {
|
||||
s.cols.Delete(d.key)
|
||||
s.cols.Set(d.newKey, col)
|
||||
if updated {
|
||||
s.cols.Delete(key)
|
||||
s.cols.Set(newKey, col)
|
||||
}
|
||||
|
||||
// >> Response
|
||||
|
||||
var d commandDetails
|
||||
var res resp.Value
|
||||
|
||||
d.command = "rename"
|
||||
d.key = key
|
||||
d.newKey = newKey
|
||||
d.updated = updated
|
||||
d.timestamp = time.Now()
|
||||
|
||||
switch msg.OutputType {
|
||||
case JSON:
|
||||
res = resp.StringValue(`{"ok":true,"elapsed":"` + time.Since(start).String() + "\"}")
|
||||
res = resp.StringValue(`{"ok":true,"elapsed":"` +
|
||||
time.Since(start).String() + "\"}")
|
||||
case RESP:
|
||||
if !nx {
|
||||
res = resp.SimpleStringValue("OK")
|
||||
|
@ -509,7 +524,7 @@ func (s *Server) cmdRename(msg *Message) (res resp.Value, d commandDetails, err
|
|||
res = resp.IntegerValue(0)
|
||||
}
|
||||
}
|
||||
return
|
||||
return res, d, nil
|
||||
}
|
||||
|
||||
func (s *Server) cmdFLUSHDB(msg *Message) (res resp.Value, d commandDetails, err error) {
|
||||
|
@ -535,7 +550,8 @@ func (s *Server) cmdFLUSHDB(msg *Message) (res resp.Value, d commandDetails, err
|
|||
d.timestamp = time.Now()
|
||||
switch msg.OutputType {
|
||||
case JSON:
|
||||
res = resp.StringValue(`{"ok":true,"elapsed":"` + time.Since(start).String() + "\"}")
|
||||
res = resp.StringValue(`{"ok":true,"elapsed":"` +
|
||||
time.Since(start).String() + "\"}")
|
||||
case RESP:
|
||||
res = resp.SimpleStringValue("OK")
|
||||
}
|
||||
|
@ -543,7 +559,8 @@ func (s *Server) cmdFLUSHDB(msg *Message) (res resp.Value, d commandDetails, err
|
|||
}
|
||||
|
||||
// SET key id [FIELD name value ...] [EX seconds] [NX|XX]
|
||||
// (OBJECT geojson)|(POINT lat lon z)|(BOUNDS minlat minlon maxlat maxlon)|(HASH geohash)|(STRING value)
|
||||
// (OBJECT geojson)|(POINT lat lon z)|(BOUNDS minlat minlon maxlat maxlon)|
|
||||
// (HASH geohash)|(STRING value)
|
||||
func (s *Server) cmdSET(msg *Message) (resp.Value, commandDetails, error) {
|
||||
start := time.Now()
|
||||
if s.config.maxMemory() > 0 && s.outOfMemory.on() {
|
||||
|
|
|
@ -604,9 +604,9 @@ func (s *Server) commandInScript(msg *Message) (
|
|||
case "expire":
|
||||
res, d, err = s.cmdEXPIRE(msg)
|
||||
case "rename":
|
||||
res, d, err = s.cmdRename(msg)
|
||||
res, d, err = s.cmdRENAME(msg)
|
||||
case "renamenx":
|
||||
res, d, err = s.cmdRename(msg)
|
||||
res, d, err = s.cmdRENAME(msg)
|
||||
case "persist":
|
||||
res, d, err = s.cmdPERSIST(msg)
|
||||
case "ttl":
|
||||
|
|
|
@ -1028,9 +1028,9 @@ func (s *Server) command(msg *Message, client *Client) (
|
|||
case "flushdb":
|
||||
res, d, err = s.cmdFLUSHDB(msg)
|
||||
case "rename":
|
||||
res, d, err = s.cmdRename(msg)
|
||||
res, d, err = s.cmdRENAME(msg)
|
||||
case "renamenx":
|
||||
res, d, err = s.cmdRename(msg)
|
||||
res, d, err = s.cmdRENAME(msg)
|
||||
case "sethook":
|
||||
res, d, err = s.cmdSetHook(msg)
|
||||
case "delhook":
|
||||
|
|
|
@ -85,44 +85,56 @@ func keys_DROP_test(mc *mockServer) error {
|
|||
Do("SCAN", "mykey", "COUNT").Str("0"),
|
||||
Do("DROP", "mykey").Str("0"),
|
||||
Do("SCAN", "mykey", "COUNT").Str("0"),
|
||||
Do("SET", "mykey", "myid1", "HASH", "9my5xp7").Str("OK"),
|
||||
Do("SET", "mykey", "myid1", "HASH", "9my5xp7").OK(),
|
||||
Do("DROP", "mykey").JSON().OK(),
|
||||
Do("DROP", "mykey").JSON().OK(),
|
||||
)
|
||||
}
|
||||
func keys_RENAME_test(mc *mockServer) error {
|
||||
return mc.DoBatch([][]interface{}{
|
||||
{"SET", "mykey", "myid1", "HASH", "9my5xp7"}, {"OK"},
|
||||
{"SET", "mykey", "myid2", "HASH", "9my5xp8"}, {"OK"},
|
||||
{"SCAN", "mykey", "COUNT"}, {2},
|
||||
{"RENAME", "mykey", "mynewkey"}, {"OK"},
|
||||
{"SCAN", "mykey", "COUNT"}, {0},
|
||||
{"SCAN", "mynewkey", "COUNT"}, {2},
|
||||
{"SET", "mykey", "myid3", "HASH", "9my5xp7"}, {"OK"},
|
||||
{"RENAME", "mykey", "mynewkey"}, {"OK"},
|
||||
{"SCAN", "mykey", "COUNT"}, {0},
|
||||
{"SCAN", "mynewkey", "COUNT"}, {1},
|
||||
{"RENAME", "foo", "mynewkey"}, {"ERR key not found"},
|
||||
{"SCAN", "mynewkey", "COUNT"}, {1},
|
||||
})
|
||||
return mc.DoBatch(
|
||||
Do("SET", "mykey", "myid1", "HASH", "9my5xp7").OK(),
|
||||
Do("SET", "mykey", "myid2", "HASH", "9my5xp8").OK(),
|
||||
Do("SCAN", "mykey", "COUNT").Str("2"),
|
||||
Do("RENAME", "foo", "mynewkey", "arg3").Err("wrong number of arguments for 'rename' command"),
|
||||
Do("RENAME", "mykey", "mynewkey").OK(),
|
||||
Do("SCAN", "mykey", "COUNT").Str("0"),
|
||||
Do("SCAN", "mynewkey", "COUNT").Str("2"),
|
||||
Do("SET", "mykey", "myid3", "HASH", "9my5xp7").OK(),
|
||||
Do("RENAME", "mykey", "mynewkey").OK(),
|
||||
Do("SCAN", "mykey", "COUNT").Str("0"),
|
||||
Do("SCAN", "mynewkey", "COUNT").Str("1"),
|
||||
Do("RENAME", "foo", "mynewkey").Err("key not found"),
|
||||
Do("SCAN", "mynewkey", "COUNT").Str("1"),
|
||||
Do("SETCHAN", "mychan", "INTERSECTS", "mynewkey", "BOUNDS", 10, 10, 20, 20).Str("1"),
|
||||
Do("RENAME", "mynewkey", "foo2").Err("key has hooks set"),
|
||||
Do("RENAMENX", "mynewkey", "foo2").Err("key has hooks set"),
|
||||
Do("SET", "mykey", "myid1", "HASH", "9my5xp7").OK(),
|
||||
Do("RENAME", "mykey", "foo2").OK(),
|
||||
Do("RENAMENX", "foo2", "foo3").Str("1"),
|
||||
Do("RENAMENX", "foo2", "foo3").Err("key not found"),
|
||||
Do("RENAME", "foo2", "foo3").JSON().Err("key not found"),
|
||||
Do("SET", "mykey", "myid1", "HASH", "9my5xp7").OK(),
|
||||
Do("RENAMENX", "mykey", "foo3").Str("0"),
|
||||
Do("RENAME", "foo3", "foo4").JSON().OK(),
|
||||
)
|
||||
}
|
||||
func keys_RENAMENX_test(mc *mockServer) error {
|
||||
return mc.DoBatch([][]interface{}{
|
||||
{"SET", "mykey", "myid1", "HASH", "9my5xp7"}, {"OK"},
|
||||
{"SET", "mykey", "myid2", "HASH", "9my5xp8"}, {"OK"},
|
||||
{"SCAN", "mykey", "COUNT"}, {2},
|
||||
{"RENAMENX", "mykey", "mynewkey"}, {1},
|
||||
{"SCAN", "mykey", "COUNT"}, {0},
|
||||
{"DROP", "mykey"}, {0},
|
||||
{"SCAN", "mykey", "COUNT"}, {0},
|
||||
{"SCAN", "mynewkey", "COUNT"}, {2},
|
||||
{"SET", "mykey", "myid3", "HASH", "9my5xp7"}, {"OK"},
|
||||
{"RENAMENX", "mykey", "mynewkey"}, {0},
|
||||
{"SCAN", "mykey", "COUNT"}, {1},
|
||||
{"SCAN", "mynewkey", "COUNT"}, {2},
|
||||
{"RENAMENX", "foo", "mynewkey"}, {"ERR key not found"},
|
||||
{"SCAN", "mynewkey", "COUNT"}, {2},
|
||||
})
|
||||
return mc.DoBatch(
|
||||
Do("SET", "mykey", "myid1", "HASH", "9my5xp7").OK(),
|
||||
Do("SET", "mykey", "myid2", "HASH", "9my5xp8").OK(),
|
||||
Do("SCAN", "mykey", "COUNT").Str("2"),
|
||||
Do("RENAMENX", "mykey", "mynewkey").Str("1"),
|
||||
Do("SCAN", "mykey", "COUNT").Str("0"),
|
||||
Do("DROP", "mykey").Str("0"),
|
||||
Do("SCAN", "mykey", "COUNT").Str("0"),
|
||||
Do("SCAN", "mynewkey", "COUNT").Str("2"),
|
||||
Do("SET", "mykey", "myid3", "HASH", "9my5xp7").OK(),
|
||||
Do("RENAMENX", "mykey", "mynewkey").Str("0"),
|
||||
Do("SCAN", "mykey", "COUNT").Str("1"),
|
||||
Do("SCAN", "mynewkey", "COUNT").Str("2"),
|
||||
Do("RENAMENX", "foo", "mynewkey").Str("ERR key not found"),
|
||||
Do("SCAN", "mynewkey", "COUNT").Str("2"),
|
||||
)
|
||||
}
|
||||
func keys_EXPIRE_test(mc *mockServer) error {
|
||||
return mc.DoBatch([][]interface{}{
|
||||
|
|
Loading…
Reference in New Issue