2014-07-08 13:10:44 +04:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/siddontang/ledisdb/ledis"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bgetCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-08 13:10:44 +04:00
|
|
|
if len(args) != 1 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.BGet(args[0]); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeBulk(v)
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bdeleteCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-08 13:10:44 +04:00
|
|
|
if len(args) != 1 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.BDelete(args[0]); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bsetbitCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-08 13:10:44 +04:00
|
|
|
if len(args) != 3 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
|
|
|
var err error
|
|
|
|
var offset int32
|
|
|
|
var val int8
|
|
|
|
|
|
|
|
offset, err = ledis.StrInt32(args[1], nil)
|
2014-07-29 12:22:07 +04:00
|
|
|
|
2014-07-08 13:10:44 +04:00
|
|
|
if err != nil {
|
2014-07-29 12:22:07 +04:00
|
|
|
return ErrOffset
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
val, err = ledis.StrInt8(args[2], nil)
|
2014-07-29 12:22:07 +04:00
|
|
|
if val != 0 && val != 1 {
|
|
|
|
return ErrBool
|
|
|
|
}
|
|
|
|
|
2014-07-08 13:10:44 +04:00
|
|
|
if err != nil {
|
2014-07-29 12:22:07 +04:00
|
|
|
return ErrBool
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if ori, err := c.db.BSetBit(args[0], offset, uint8(val)); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(int64(ori))
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bgetbitCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-08 13:10:44 +04:00
|
|
|
if len(args) != 2 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
|
|
|
offset, err := ledis.StrInt32(args[1], nil)
|
2014-07-29 12:22:07 +04:00
|
|
|
|
2014-07-08 13:10:44 +04:00
|
|
|
if err != nil {
|
2014-07-29 12:22:07 +04:00
|
|
|
return ErrOffset
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.BGetBit(args[0], offset); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(int64(v))
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bmsetbitCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-08 13:10:44 +04:00
|
|
|
if len(args) < 3 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
|
|
|
key := args[0]
|
|
|
|
if len(args[1:])&1 != 0 {
|
|
|
|
return ErrCmdParams
|
|
|
|
} else {
|
|
|
|
args = args[1:]
|
|
|
|
}
|
|
|
|
|
|
|
|
var err error
|
|
|
|
var offset int32
|
|
|
|
var val int8
|
|
|
|
|
|
|
|
pairs := make([]ledis.BitPair, len(args)>>1)
|
|
|
|
for i := 0; i < len(pairs); i++ {
|
|
|
|
offset, err = ledis.StrInt32(args[i<<1], nil)
|
2014-07-29 12:22:07 +04:00
|
|
|
|
2014-07-08 13:10:44 +04:00
|
|
|
if err != nil {
|
2014-07-29 12:22:07 +04:00
|
|
|
return ErrOffset
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
val, err = ledis.StrInt8(args[i<<1+1], nil)
|
2014-07-29 12:22:07 +04:00
|
|
|
if val != 0 && val != 1 {
|
|
|
|
return ErrBool
|
|
|
|
}
|
|
|
|
|
2014-07-08 13:10:44 +04:00
|
|
|
if err != nil {
|
2014-07-29 12:22:07 +04:00
|
|
|
return ErrBool
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
pairs[i].Pos = offset
|
|
|
|
pairs[i].Val = uint8(val)
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if place, err := c.db.BMSetBit(key, pairs...); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(place)
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bcountCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-08 13:10:44 +04:00
|
|
|
argCnt := len(args)
|
|
|
|
|
|
|
|
if !(argCnt > 0 && argCnt <= 3) {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
|
|
|
// BCount(key []byte, start int32, end int32) (cnt int32, err error) {
|
|
|
|
|
|
|
|
var err error
|
|
|
|
var start, end int32 = 0, -1
|
|
|
|
|
|
|
|
if argCnt > 1 {
|
|
|
|
start, err = ledis.StrInt32(args[1], nil)
|
|
|
|
if err != nil {
|
2014-07-29 12:22:07 +04:00
|
|
|
return ErrValue
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if argCnt > 2 {
|
|
|
|
end, err = ledis.StrInt32(args[2], nil)
|
|
|
|
if err != nil {
|
2014-07-29 12:22:07 +04:00
|
|
|
return ErrValue
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if cnt, err := c.db.BCount(args[0], start, end); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(int64(cnt))
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func boptCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-08 13:10:44 +04:00
|
|
|
if len(args) < 2 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
|
|
|
opDesc := strings.ToLower(ledis.String(args[0]))
|
|
|
|
dstKey := args[1]
|
|
|
|
srcKeys := args[2:]
|
|
|
|
|
|
|
|
var op uint8
|
|
|
|
switch opDesc {
|
|
|
|
case "and":
|
|
|
|
op = ledis.OPand
|
|
|
|
case "or":
|
|
|
|
op = ledis.OPor
|
|
|
|
case "xor":
|
|
|
|
op = ledis.OPxor
|
|
|
|
case "not":
|
|
|
|
op = ledis.OPnot
|
|
|
|
default:
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-07-29 12:22:07 +04:00
|
|
|
if len(srcKeys) == 0 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
2014-08-25 10:18:23 +04:00
|
|
|
if blen, err := c.db.BOperation(op, dstKey, srcKeys...); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(int64(blen))
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bexpireCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-29 12:22:07 +04:00
|
|
|
if len(args) != 2 {
|
2014-07-08 13:10:44 +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-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.BExpire(args[0], duration); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(v)
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bexpireAtCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-29 12:22:07 +04:00
|
|
|
if len(args) != 2 {
|
2014-07-08 13:10:44 +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-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.BExpireAt(args[0], when); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(v)
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bttlCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-29 12:22:07 +04:00
|
|
|
if len(args) != 1 {
|
2014-07-08 13:10:44 +04:00
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if v, err := c.db.BTTL(args[0]); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(v)
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func bpersistCommand(c *client) error {
|
|
|
|
args := c.args
|
2014-07-08 13:10:44 +04:00
|
|
|
if len(args) != 1 {
|
|
|
|
return ErrCmdParams
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
if n, err := c.db.BPersist(args[0]); err != nil {
|
2014-07-08 13:10:44 +04:00
|
|
|
return err
|
|
|
|
} else {
|
2014-08-25 10:18:23 +04:00
|
|
|
c.resp.writeInteger(n)
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-08-26 19:21:45 +04:00
|
|
|
func bscanCommand(c *client) 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-08-27 06:29:17 +04:00
|
|
|
if ay, err := c.db.BScan(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 {
|
2014-08-27 06:29:17 +04:00
|
|
|
data[0] = []byte("")
|
2014-08-26 19:21:45 +04:00
|
|
|
} else {
|
2014-08-27 06:29:17 +04:00
|
|
|
data[0] = ay[len(ay)-1]
|
2014-08-26 19:21:45 +04:00
|
|
|
}
|
|
|
|
data[1] = ay
|
|
|
|
c.resp.writeArray(data)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-07-08 13:10:44 +04:00
|
|
|
func init() {
|
|
|
|
register("bget", bgetCommand)
|
|
|
|
register("bdelete", bdeleteCommand)
|
|
|
|
register("bsetbit", bsetbitCommand)
|
|
|
|
register("bgetbit", bgetbitCommand)
|
|
|
|
register("bmsetbit", bmsetbitCommand)
|
|
|
|
register("bcount", bcountCommand)
|
|
|
|
register("bopt", boptCommand)
|
|
|
|
register("bexpire", bexpireCommand)
|
2014-07-29 12:22:07 +04:00
|
|
|
register("bexpireat", bexpireAtCommand)
|
2014-07-08 13:10:44 +04:00
|
|
|
register("bttl", bttlCommand)
|
|
|
|
register("bpersist", bpersistCommand)
|
2014-08-26 19:21:45 +04:00
|
|
|
register("bscan", bscanCommand)
|
2014-07-08 13:10:44 +04:00
|
|
|
}
|