support XUSE db THEN command

To solve https://github.com/siddontang/ledisdb/issues/149, but I prefer
XUSE db THEN command like IFFFT, aha.
This commit is contained in:
siddontang 2015-03-21 20:33:57 +08:00
parent 3d806ad179
commit 5223f5d8eb
3 changed files with 92 additions and 3 deletions

View File

@ -134,6 +134,11 @@ func (c *respClient) run() {
reqData, err := c.readRequest() reqData, err := c.readRequest()
if err == nil { if err == nil {
err = c.handleRequest(reqData) err = c.handleRequest(reqData)
c.cmd = ""
c.args = nil
c.ar.Reset()
} }
if err != nil { if err != nil {
@ -154,6 +159,16 @@ func (c *respClient) handleRequest(reqData [][]byte) error {
c.cmd = hack.String(lowerSlice(reqData[0])) c.cmd = hack.String(lowerSlice(reqData[0]))
c.args = reqData[1:] c.args = reqData[1:]
} }
if c.cmd == "xuse" {
err := c.handleUseThenCmd()
if err != nil {
c.resp.writeError(err)
c.resp.flush()
return nil
}
}
if c.cmd == "quit" { if c.cmd == "quit" {
c.activeQuit = true c.activeQuit = true
c.resp.writeStatus(OK) c.resp.writeStatus(OK)
@ -164,10 +179,35 @@ func (c *respClient) handleRequest(reqData [][]byte) error {
c.perform() c.perform()
c.cmd = "" return nil
c.args = nil }
c.ar.Reset() // XUSE db THEN command
func (c *respClient) handleUseThenCmd() error {
if len(c.args) <= 2 {
// invalid command format
return fmt.Errorf("invalid format for XUSE, must XUSE db THEN your command")
}
if hack.String(upperSlice(c.args[1])) != "THEN" {
// invalid command format, just resturn here
return fmt.Errorf("invalid format for XUSE, must XUSE db THEN your command")
}
index, err := strconv.Atoi(hack.String(c.args[0]))
if err != nil {
return fmt.Errorf("invalid db for XUSE, err %v", err)
}
db, err := c.app.ldb.Select(index)
if err != nil {
return fmt.Errorf("invalid db for XUSE, err %v", err)
}
c.db = db
c.cmd = hack.String(lowerSlice(c.args[2]))
c.args = c.args[3:]
return nil return nil
} }

38
server/cmd_server_test.go Normal file
View File

@ -0,0 +1,38 @@
package server
import (
"github.com/siddontang/goredis"
"testing"
)
func TestXuse(t *testing.T) {
c1 := getTestConn()
defer c1.Close()
c2 := getTestConn()
defer c2.Close()
_, err := c1.Do("XUSE", "1", "THEN", "SET", "tmp_select_key", "1")
if err != nil {
t.Fatal(err)
}
_, err = goredis.Int(c2.Do("GET", "tmp_select_key"))
if err != goredis.ErrNil {
t.Fatal(err)
}
n, _ := goredis.Int(c2.Do("XUSE", "1", "THEN", "GET", "tmp_select_key"))
if n != 1 {
t.Fatal(n)
}
n, _ = goredis.Int(c2.Do("GET", "tmp_select_key"))
if n != 1 {
t.Fatal(n)
}
c1.Do("SELECT", 0)
c2.Do("SELECT", 0)
}

View File

@ -134,3 +134,14 @@ func lowerSlice(buf []byte) []byte {
} }
return buf return buf
} }
func upperSlice(buf []byte) []byte {
for i, r := range buf {
if 'a' <= r && r <= 'z' {
r -= 'a' - 'A'
}
buf[i] = r
}
return buf
}