2014-05-16 11:03:23 +04:00
|
|
|
package server
|
2014-05-03 10:55:12 +04:00
|
|
|
|
2014-05-16 11:03:23 +04:00
|
|
|
import (
|
2014-09-24 08:34:21 +04:00
|
|
|
"github.com/siddontang/go/hack"
|
2014-05-16 11:03:23 +04:00
|
|
|
"github.com/siddontang/ledisdb/ledis"
|
2014-08-26 19:21:45 +04:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2014-05-16 11:03:23 +04:00
|
|
|
)
|
2014-05-04 15:02:55 +04:00
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func getCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) != 1 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.Get(args[0]); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeBulk(v)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func setCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-06-11 12:49:17 +04:00
|
|
|
if len(args) != 2 {
|
2014-05-04 15:02:55 +04:00
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if err := c.db.Set(args[0], args[1]); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeStatus(OK)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func getsetCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) != 2 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.GetSet(args[0], args[1]); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeBulk(v)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func setnxCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) != 2 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.SetNX(args[0], args[1]); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-10-26 10:15:43 +03:00
|
|
|
func setexCommand(c *client) error {
|
|
|
|
args := c.args
|
|
|
|
if len(args) != 3 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
|
|
|
sec, err := ledis.StrInt64(args[1], nil)
|
|
|
|
if err != nil {
|
|
|
|
return ErrValue
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := c.db.SetEX(args[0], sec, args[2]); err != nil {
|
|
|
|
return err
|
|
|
|
} else {
|
|
|
|
c.resp.writeStatus(OK)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func existsCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) != 1 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.Exists(args[0]); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func incrCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) != 1 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.Incr(c.args[0]); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func decrCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) != 1 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.Decr(c.args[0]); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func incrbyCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) != 2 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-05-16 11:03:23 +04:00
|
|
|
delta, err := ledis.StrInt64(args[1], nil)
|
2014-05-04 15:02:55 +04:00
|
|
|
if err != nil {
|
2014-07-25 13:26:29 +04:00
|
|
|
return ErrValue
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.IncrBy(c.args[0], delta); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func decrbyCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) != 2 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-05-16 11:03:23 +04:00
|
|
|
delta, err := ledis.StrInt64(args[1], nil)
|
2014-05-04 15:02:55 +04:00
|
|
|
if err != nil {
|
2014-07-25 13:26:29 +04:00
|
|
|
return ErrValue
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.DecrBy(c.args[0], delta); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func delCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) == 0 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.Del(args...); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func msetCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) == 0 || len(args)%2 != 0 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-05-16 11:03:23 +04:00
|
|
|
kvs := make([]ledis.KVPair, len(args)/2)
|
2014-05-16 04:56:32 +04:00
|
|
|
for i := 0; i < len(kvs); i++ {
|
|
|
|
kvs[i].Key = args[2*i]
|
|
|
|
kvs[i].Value = args[2*i+1]
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if err := c.db.MSet(kvs...); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeStatus(OK)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
2014-05-03 10:55:12 +04:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
// func setexCommand(c *client) error {
|
2014-05-04 15:02:55 +04:00
|
|
|
// return nil
|
|
|
|
// }
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func mgetCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-05-04 15:02:55 +04:00
|
|
|
if len(args) == 0 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.MGet(args...); err != nil {
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeSliceArray(v)
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func expireCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-06-30 07:23:14 +04:00
|
|
|
if len(args) != 2 {
|
2014-06-16 15:24:37 +04:00
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
|
|
|
duration, err := ledis.StrInt64(args[1], nil)
|
|
|
|
if err != nil {
|
2014-07-25 13:26:29 +04:00
|
|
|
return ErrValue
|
2014-06-16 15:24:37 +04:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.Expire(args[0], duration); err != nil {
|
2014-06-16 15:24:37 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(v)
|
2014-06-16 15:24:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func expireAtCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-06-30 07:23:14 +04:00
|
|
|
if len(args) != 2 {
|
2014-06-16 15:24:37 +04:00
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
|
|
|
when, err := ledis.StrInt64(args[1], nil)
|
|
|
|
if err != nil {
|
2014-07-25 13:26:29 +04:00
|
|
|
return ErrValue
|
2014-06-16 15:24:37 +04:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.ExpireAt(args[0], when); err != nil {
|
2014-06-16 15:24:37 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(v)
|
2014-06-16 15:24:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func ttlCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-06-30 07:23:14 +04:00
|
|
|
if len(args) != 1 {
|
2014-06-16 15:24:37 +04:00
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.TTL(args[0]); err != nil {
|
2014-06-16 15:24:37 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(v)
|
2014-06-16 15:24:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func persistCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-06-24 08:44:44 +04:00
|
|
|
if len(args) != 1 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.Persist(args[0]); err != nil {
|
2014-06-24 08:44:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-06-24 08:44:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-27 06:29:17 +04:00
|
|
|
func parseScanArgs(c *client) (key []byte, match string, count int, err error) {
|
2014-08-26 19:21:45 +04:00
|
|
|
args := c.args
|
|
|
|
count = 10
|
|
|
|
|
|
|
|
switch len(args) {
|
|
|
|
case 0:
|
|
|
|
key = nil
|
|
|
|
return
|
|
|
|
case 1, 3, 5:
|
|
|
|
key = args[0]
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
err = ErrCmdParams
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(args) == 3 {
|
2014-09-24 08:34:21 +04:00
|
|
|
switch strings.ToLower(hack.String(args[1])) {
|
2014-08-26 19:21:45 +04:00
|
|
|
case "match":
|
2014-09-24 08:34:21 +04:00
|
|
|
match = hack.String(args[2])
|
2014-08-26 19:21:45 +04:00
|
|
|
case "count":
|
2014-09-24 08:34:21 +04:00
|
|
|
count, err = strconv.Atoi(hack.String(args[2]))
|
2014-08-26 19:21:45 +04:00
|
|
|
default:
|
|
|
|
err = ErrCmdParams
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else if len(args) == 5 {
|
2014-09-24 08:34:21 +04:00
|
|
|
if strings.ToLower(hack.String(args[1])) != "match" {
|
2014-08-26 19:21:45 +04:00
|
|
|
err = ErrCmdParams
|
|
|
|
return
|
2014-09-24 08:34:21 +04:00
|
|
|
} else if strings.ToLower(hack.String(args[3])) != "count" {
|
2014-08-26 19:21:45 +04:00
|
|
|
err = ErrCmdParams
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-09-24 08:34:21 +04:00
|
|
|
match = hack.String(args[2])
|
|
|
|
count, err = strconv.Atoi(hack.String(args[4]))
|
2014-09-18 05:08:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if count <= 0 {
|
|
|
|
err = ErrCmdParams
|
2014-08-26 19:21:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-10-20 18:36:16 +04:00
|
|
|
func xscanGeneric(c *client,
|
|
|
|
f func(key []byte, count int, inclusive bool, match string) ([][]byte, error)) error {
|
2014-08-27 06:29:17 +04:00
|
|
|
key, match, count, err := parseScanArgs(c)
|
2014-08-26 19:21:45 +04:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-10-20 18:36:16 +04:00
|
|
|
if ay, err := f(key, count, false, match); err != nil {
|
2014-08-26 19:21:45 +04:00
|
|
|
return err
|
|
|
|
} else {
|
|
|
|
data := make([]interface{}, 2)
|
|
|
|
if len(ay) < count {
|
|
|
|
data[0] = []byte("")
|
|
|
|
} else {
|
|
|
|
data[0] = ay[len(ay)-1]
|
|
|
|
}
|
|
|
|
data[1] = ay
|
|
|
|
c.resp.writeArray(data)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-10-20 18:36:16 +04:00
|
|
|
func xscanCommand(c *client) error {
|
|
|
|
return xscanGeneric(c, c.db.Scan)
|
|
|
|
}
|
|
|
|
|
|
|
|
func xrevscanCommand(c *client) error {
|
|
|
|
return xscanGeneric(c, c.db.RevScan)
|
|
|
|
}
|
|
|
|
|
2014-05-03 10:55:12 +04:00
|
|
|
func init() {
|
|
|
|
register("decr", decrCommand)
|
|
|
|
register("decrby", decrbyCommand)
|
|
|
|
register("del", delCommand)
|
|
|
|
register("exists", existsCommand)
|
|
|
|
register("get", getCommand)
|
|
|
|
register("getset", getsetCommand)
|
|
|
|
register("incr", incrCommand)
|
|
|
|
register("incrby", incrbyCommand)
|
|
|
|
register("mget", mgetCommand)
|
|
|
|
register("mset", msetCommand)
|
|
|
|
register("set", setCommand)
|
|
|
|
register("setnx", setnxCommand)
|
2014-10-26 10:15:43 +03:00
|
|
|
register("setex", setexCommand)
|
2014-06-16 15:24:37 +04:00
|
|
|
register("expire", expireCommand)
|
|
|
|
register("expireat", expireAtCommand)
|
|
|
|
register("ttl", ttlCommand)
|
2014-06-24 08:44:44 +04:00
|
|
|
register("persist", persistCommand)
|
2014-09-09 05:53:26 +04:00
|
|
|
register("xscan", xscanCommand)
|
2014-10-20 18:36:16 +04:00
|
|
|
register("xrevscan", xrevscanCommand)
|
2014-05-03 10:55:12 +04:00
|
|
|
}
|