forked from mirror/ledisdb
rm server/http
This commit is contained in:
parent
e46554e9f6
commit
a88c8c46d8
|
@ -1,34 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
ERR_ARGUMENT_FORMAT = "wrong number of arguments for '%s' command"
|
|
||||||
MSG_OK = "OK"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrValue = errors.New("value is not an integer or out of range")
|
|
||||||
ErrSyntax = errors.New("syntax error")
|
|
||||||
)
|
|
||||||
|
|
||||||
type commandFunc func(*ledis.DB, ...string) (interface{}, error)
|
|
||||||
|
|
||||||
var regCmds = map[string]commandFunc{}
|
|
||||||
|
|
||||||
func register(name string, f commandFunc) {
|
|
||||||
if _, ok := regCmds[strings.ToLower(name)]; ok {
|
|
||||||
panic(fmt.Sprintf("%s has been registered", name))
|
|
||||||
}
|
|
||||||
regCmds[name] = f
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookup(name string) commandFunc {
|
|
||||||
return regCmds[strings.ToLower(name)]
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var once sync.Once
|
|
||||||
var ldb *ledis.Ledis
|
|
||||||
|
|
||||||
func getTestDB() *ledis.DB {
|
|
||||||
f := func() {
|
|
||||||
var err error
|
|
||||||
if _, err = os.Stat("/tmp/test_http_api_db"); err == nil {
|
|
||||||
if err = os.RemoveAll("/tmp/test_http_api_db"); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
} else if !os.IsNotExist(err) {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
var cfg ledis.Config
|
|
||||||
cfg.DataDir = "/tmp/test_http_api_db"
|
|
||||||
cfg.DataDB.BlockSize = 32768
|
|
||||||
cfg.DataDB.WriteBufferSize = 20971520
|
|
||||||
cfg.DataDB.CacheSize = 20971520
|
|
||||||
cfg.DataDB.Compression = true
|
|
||||||
|
|
||||||
ldb, err = ledis.Open(&cfg)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
once.Do(f)
|
|
||||||
db, err := ldb.Select(0)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return db
|
|
||||||
}
|
|
|
@ -1,228 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func bgetCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bget")
|
|
||||||
}
|
|
||||||
if v, err := db.BGet([]byte(args[0])); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return ledis.String(v), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bdeleteCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bdelete")
|
|
||||||
}
|
|
||||||
if n, err := db.BDelete([]byte(args[0])); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bsetbitCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bsetbit")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
offset, err := strconv.ParseInt(args[1], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
val, err := strconv.ParseUint(args[2], 10, 8)
|
|
||||||
if ori, err := db.BSetBit(key, int32(offset), uint8(val)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return ori, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bgetbitCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bgetbit")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
offset, err := strconv.ParseInt(args[1], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, err := db.BGetBit(key, int32(offset)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func bmsetbitCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bmsetbit")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if len(args[1:])%2 != 0 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bmsetbit")
|
|
||||||
} else {
|
|
||||||
args = args[1:]
|
|
||||||
}
|
|
||||||
pairs := make([]ledis.BitPair, len(args)/2)
|
|
||||||
for i := 0; i < len(pairs); i++ {
|
|
||||||
offset, err := strconv.ParseInt(args[i*2], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
val, err := strconv.ParseUint(args[i*2+1], 10, 8)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pairs[i].Pos = int32(offset)
|
|
||||||
pairs[i].Val = uint8(val)
|
|
||||||
}
|
|
||||||
if place, err := db.BMSetBit(key, pairs...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return place, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bcountCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
argCnt := len(args)
|
|
||||||
if argCnt > 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bcount")
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
var start, end int64 = 0, -1
|
|
||||||
if argCnt > 1 {
|
|
||||||
if start, err = strconv.ParseInt(args[1], 10, 32); err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if argCnt > 2 {
|
|
||||||
if end, err = strconv.ParseInt(args[2], 10, 32); err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if cnt, err := db.BCount(key, int32(start), int32(end)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return cnt, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func boptCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bopt")
|
|
||||||
}
|
|
||||||
opDesc := strings.ToLower(args[0])
|
|
||||||
dstKey := []byte(args[1])
|
|
||||||
|
|
||||||
var srcKeys = [][]byte{}
|
|
||||||
if len(args) >= 3 {
|
|
||||||
srcKeys = make([][]byte, len(args[2:]))
|
|
||||||
for i, arg := range args[2:] {
|
|
||||||
srcKeys[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 nil, fmt.Errorf("invalid argument '%s' for 'bopt' command", opDesc)
|
|
||||||
}
|
|
||||||
if blen, err := db.BOperation(op, dstKey, srcKeys...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return blen, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bexpireCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bexpire")
|
|
||||||
}
|
|
||||||
duration, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.BExpire(key, duration); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bexpireatCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bexpireat")
|
|
||||||
}
|
|
||||||
when, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.BExpireAt(key, when); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bttlCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bttl")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.BTTL(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bpersistCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "bpersist")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.BPersist(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
register("bexpireat", bexpireatCommand)
|
|
||||||
register("bttl", bttlCommand)
|
|
||||||
register("bpersist", bpersistCommand)
|
|
||||||
}
|
|
|
@ -1,274 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBgetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
db.BSetBit([]byte("test_bget"), 0, 1)
|
|
||||||
db.BSetBit([]byte("test_bget"), 1, 1)
|
|
||||||
db.BSetBit([]byte("test_bget"), 2, 1)
|
|
||||||
|
|
||||||
_, err := bgetCommand(db, "test_bget", "a", "b", "c")
|
|
||||||
if err == nil || err.Error() != "wrong number of arguments for 'bget' command" {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := bgetCommand(db, "test_bget")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
str := r.(string)
|
|
||||||
if str != "\x07" {
|
|
||||||
t.Fatalf("wrong result of 'bget': %v", []byte(str))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBDeleteCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
|
|
||||||
_, err := bdeleteCommand(db, "test_bdelete", "a", "b", "c")
|
|
||||||
if err == nil || err.Error() != "wrong number of arguments for 'bdelete' command" {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BSetBit([]byte("test_bdelete"), 0, 1)
|
|
||||||
db.BSetBit([]byte("test_bdelete"), 1, 1)
|
|
||||||
db.BSetBit([]byte("test_bdelete"), 2, 1)
|
|
||||||
n, err := bdeleteCommand(db, "test_bdelete")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if n.(int64) != 1 {
|
|
||||||
t.Fatalf("wrong result: %v", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err = bdeleteCommand(db, "test_bdelete_not_exit")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if n.(int64) != 0 {
|
|
||||||
t.Fatalf("wrong result: %v", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBSetbitCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := bsetbitCommand(db, "test_bsetbit", "a", "b", "c")
|
|
||||||
if err == nil || err.Error() != "wrong number of arguments for 'bsetbit' command" {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
n, err := bsetbitCommand(db, "test_bsetbit", "1", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if n.(uint8) != 0 {
|
|
||||||
t.Fatal("wrong result: %v", n)
|
|
||||||
}
|
|
||||||
n, err = db.BGetBit([]byte("test_bsetbit"), 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if n.(uint8) != 1 {
|
|
||||||
t.Fatalf("wrong result: %v", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBMsetbitCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := bmsetbitCommand(db, "test_bmsetbit", "a", "b", "c")
|
|
||||||
|
|
||||||
if err == nil || err.Error() != "wrong number of arguments for 'bmsetbit' command" {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
n, err := bmsetbitCommand(db, "test_bmsetbit", "1", "1", "3", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if n.(int64) != 2 {
|
|
||||||
t.Fatalf("wrong result: %v", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBCountCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := bcountCommand(db, "test_bcount", "a", "b", "c")
|
|
||||||
if err == nil || err.Error() != "wrong number of arguments for 'bcount' command" {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BSetBit([]byte("test_bcount"), 1, 1)
|
|
||||||
db.BSetBit([]byte("test_bcount"), 3, 1)
|
|
||||||
|
|
||||||
cnt, err := bcountCommand(db, "test_bcount", "0", "3")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if cnt.(int32) != 2 {
|
|
||||||
t.Fatal("invalid value", cnt)
|
|
||||||
}
|
|
||||||
|
|
||||||
cnt, err = bcountCommand(db, "test_bcount", "2")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if cnt.(int32) != 1 {
|
|
||||||
t.Fatal("invalid value", cnt)
|
|
||||||
}
|
|
||||||
|
|
||||||
cnt, err = bcountCommand(db, "test_bcount")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if cnt.(int32) != 2 {
|
|
||||||
t.Fatal("invalid value", cnt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBOptCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := boptCommand(db, "test_bopt")
|
|
||||||
if err == nil || err.Error() != "wrong number of arguments for 'bopt' command" {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BSetBit([]byte("test_bopt_and_1"), 1, 1)
|
|
||||||
db.BSetBit([]byte("test_bopt_and_2"), 1, 1)
|
|
||||||
|
|
||||||
_, err = boptCommand(db, "and", "test_bopt_and_3", "test_bopt_and_1", "test_bopt_and_2")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
r, _ := db.BGet([]byte("test_bopt_and_3"))
|
|
||||||
if len(r) != 1 || r[0] != 2 {
|
|
||||||
t.Fatalf("invalid result %v", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BSetBit([]byte("test_bopt_or_1"), 0, 1)
|
|
||||||
db.BSetBit([]byte("test_bopt_or_1"), 1, 1)
|
|
||||||
db.BSetBit([]byte("test_bopt_or_2"), 0, 1)
|
|
||||||
db.BSetBit([]byte("test_bopt_or_2"), 2, 1)
|
|
||||||
|
|
||||||
_, err = boptCommand(db, "or", "test_bopt_or_3", "test_bopt_or_1", "test_bopt_or_2")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
r, _ = db.BGet([]byte("test_bopt_or_3"))
|
|
||||||
if len(r) != 1 || r[0] != 7 {
|
|
||||||
t.Fatalf("invalid result %v", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BSetBit([]byte("test_bopt_xor_1"), 0, 1)
|
|
||||||
db.BSetBit([]byte("test_bopt_xor_1"), 1, 1)
|
|
||||||
db.BSetBit([]byte("test_bopt_xor_2"), 0, 1)
|
|
||||||
db.BSetBit([]byte("test_bopt_xor_2"), 2, 1)
|
|
||||||
|
|
||||||
_, err = boptCommand(db, "xor", "test_bopt_xor_3", "test_bopt_xor_1", "test_bopt_xor_2")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
r, _ = db.BGet([]byte("test_bopt_xor_3"))
|
|
||||||
if len(r) != 1 || r[0] != 6 {
|
|
||||||
t.Fatalf("invalid result %v", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BSetBit([]byte("test_bopt_not_1"), 0, 1)
|
|
||||||
db.BSetBit([]byte("test_bopt_not_1"), 1, 0)
|
|
||||||
_, err = boptCommand(db, "not", "test_bopt_not_2", "test_bopt_not_1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
r, _ = db.BGet([]byte("test_bopt_not_2"))
|
|
||||||
if len(r) != 1 || r[0] != 2 {
|
|
||||||
t.Fatalf("invalid result %v", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = boptCommand(db, "invalid_opt", "abc")
|
|
||||||
if err == nil || err.Error() != "invalid argument 'invalid_opt' for 'bopt' command" {
|
|
||||||
t.Fatal("invalid err ", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBExpireCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := bexpireCommand(db, "test_bexpire", "a", "b")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "bexpire") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BSetBit([]byte("test_bexpire"), 1, 1)
|
|
||||||
bexpireCommand(db, "test_bexpire", "1000")
|
|
||||||
|
|
||||||
n, err := db.BTTL([]byte("test_bexpire"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if n == -1 {
|
|
||||||
t.Fatal("wrong result ", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBExpireAtCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := bexpireatCommand(db, "test_bexpireat", "a", "b")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "bexpireat") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BSetBit([]byte("test_bexpireat"), 1, 1)
|
|
||||||
expireAt := fmt.Sprintf("%d", time.Now().Unix()+100)
|
|
||||||
if _, err = bexpireatCommand(db, "test_bexpireat", expireAt); err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err := db.BTTL([]byte("test_bexpireat"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if n == -1 {
|
|
||||||
t.Fatal("wrong result ", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBTTLCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
|
|
||||||
_, err := bttlCommand(db, "test_bttl", "a", "b")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "bttl") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := bttlCommand(db, "test_bttl")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != -1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBPersistCommand(t *testing.T) {
|
|
||||||
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := bpersistCommand(db, "test_bpersist", "a", "b")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "bpersist") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := bpersistCommand(db, "test_bpersist")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,311 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func hsetCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hset")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
field := []byte(args[1])
|
|
||||||
value := []byte(args[2])
|
|
||||||
if n, err := db.HSet(key, field, value); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hgetCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hget")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
field := []byte(args[1])
|
|
||||||
|
|
||||||
if v, err := db.HGet(key, field); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
if v == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return ledis.String(v), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hexistsCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hexists")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
field := []byte(args[1])
|
|
||||||
|
|
||||||
var n int64 = 1
|
|
||||||
if v, err := db.HGet(key, field); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
if v == nil {
|
|
||||||
n = 0
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hdelCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hdel")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
fields := make([][]byte, len(args[1:]))
|
|
||||||
for i, arg := range args[1:] {
|
|
||||||
fields[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n, err := db.HDel(key, fields...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hlenCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hlen")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.HLen(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hincrbyCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hincrby")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
field := []byte(args[1])
|
|
||||||
delta, err := strconv.ParseInt(args[2], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
var n int64
|
|
||||||
if n, err = db.HIncrBy(key, field, delta); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hmsetCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hmset")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args[1:])%2 != 0 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hmset")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
args = args[1:]
|
|
||||||
kvs := make([]ledis.FVPair, len(args)/2)
|
|
||||||
for i := 0; i < len(kvs); i++ {
|
|
||||||
kvs[i].Field = []byte(args[2*i])
|
|
||||||
kvs[i].Value = []byte(args[2*i+1])
|
|
||||||
}
|
|
||||||
if err := db.HMset(key, kvs...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return []interface{}{true, MSG_OK}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hmgetCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hmget")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
fields := make([][]byte, len(args[1:]))
|
|
||||||
for i, arg := range args[1:] {
|
|
||||||
fields[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
if vals, err := db.HMget(key, fields...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
arr := make([]interface{}, len(vals))
|
|
||||||
for i, v := range vals {
|
|
||||||
if v == nil {
|
|
||||||
arr[i] = nil
|
|
||||||
} else {
|
|
||||||
arr[i] = ledis.String(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arr, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hgetallCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hgetall")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if fvs, err := db.HGetAll(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
var m = make(map[string]string)
|
|
||||||
for _, fv := range fvs {
|
|
||||||
m[ledis.String(fv.Field)] = ledis.String(fv.Value)
|
|
||||||
}
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hkeysCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hkeys")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if fields, err := db.HKeys(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
arr := make([]string, len(fields))
|
|
||||||
for i, f := range fields {
|
|
||||||
arr[i] = ledis.String(f)
|
|
||||||
}
|
|
||||||
return arr, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hvalsCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hvals")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if vals, err := db.HValues(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
var arr = make([]string, len(vals))
|
|
||||||
for i, v := range vals {
|
|
||||||
arr[i] = ledis.String(v)
|
|
||||||
}
|
|
||||||
return arr, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hclearCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hclear")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.HClear(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hmclearCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hmclear")
|
|
||||||
}
|
|
||||||
keys := make([][]byte, len(args))
|
|
||||||
for i, arg := range args {
|
|
||||||
keys[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n, err := db.HMclear(keys...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hexpireCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hexpire")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
duration, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
if v, err := db.HExpire(key, duration); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hexpireAtCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hexpireat")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
when, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, err := db.HExpireAt(key, when); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func httlCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "httl")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.HTTL(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func hpersistCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "hpersist")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.HPersist(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
register("hdel", hdelCommand)
|
|
||||||
register("hexists", hexistsCommand)
|
|
||||||
register("hget", hgetCommand)
|
|
||||||
register("hgetall", hgetallCommand)
|
|
||||||
register("hincrby", hincrbyCommand)
|
|
||||||
register("hkeys", hkeysCommand)
|
|
||||||
register("hlen", hlenCommand)
|
|
||||||
register("hmget", hmgetCommand)
|
|
||||||
register("hmset", hmsetCommand)
|
|
||||||
register("hset", hsetCommand)
|
|
||||||
register("hvals", hvalsCommand)
|
|
||||||
|
|
||||||
//ledisdb special command
|
|
||||||
|
|
||||||
register("hclear", hclearCommand)
|
|
||||||
register("hmclear", hmclearCommand)
|
|
||||||
register("hexpire", hexpireCommand)
|
|
||||||
register("hexpireat", hexpireAtCommand)
|
|
||||||
register("httl", httlCommand)
|
|
||||||
register("hpersist", hpersistCommand)
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,369 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestHSetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hsetCommand(db, "test_hset")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hset") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err := hsetCommand(db, "test_hset", "f", "v")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", n)
|
|
||||||
}
|
|
||||||
v, err := db.HGet([]byte("test_hset"), []byte("f"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if string(v) != "v" {
|
|
||||||
t.Fatalf("invalid result %s", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHGetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hgetCommand(db, "test_hget")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hget") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
if _, err := db.HSet([]byte("test_hget"), []byte("f"), []byte("v")); err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hgetCommand(db, "test_hget", "f")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(string) != "v" {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHExistsCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hexistsCommand(db, "test_hexists")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hexists") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.HSet([]byte("test_hexists"), []byte("f"), []byte("v"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hexistsCommand(db, "test_hexists", "f")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHDelCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hdelCommand(db, "test_hdel")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hdel") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.HSet([]byte("test_hdel"), []byte("f"), []byte("v"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hdelCommand(db, "test_hdel", "f")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := db.HGet([]byte("test_hdel"), []byte("f"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if r != nil {
|
|
||||||
t.Fatalf("invalid result %v", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHLenCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hlenCommand(db, "test_hlen", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hlen") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.HSet([]byte("test_hlen"), []byte("f1"), []byte("v1"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
_, err = db.HSet([]byte("test_hlen"), []byte("f2"), []byte("v2"))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hlenCommand(db, "test_hlen")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 2 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHIncrbyCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hincrbyCommand(db, "test_hincrby")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hincrby") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
_, err = db.HSet([]byte("test_hincrby"), []byte("f"), []byte("10"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = hincrbyCommand(db, "test_hincrby", "f", "x")
|
|
||||||
if err != ErrValue {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hincrbyCommand(db, "test_hincrby", "f", "10")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 20 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHMsetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hmsetCommand(db, "test_hmset")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hmset") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = hmsetCommand(db, "test_hmset", "f1", "v1", "f2", "v2")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := db.HGet([]byte("test_hmset"), []byte("f1"))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if string(v) != "v1" {
|
|
||||||
t.Fatalf("invalid result %s", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err = db.HGet([]byte("test_hmset"), []byte("f2"))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if string(v) != "v2" {
|
|
||||||
t.Fatalf("invalid result %s", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHMgetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hmgetCommand(db, "test_hmget")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hmget") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.HSet([]byte("test_hmget"), []byte("f1"), []byte("v1"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.HSet([]byte("test_hmget"), []byte("f2"), []byte("v2"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hmgetCommand(db, "test_hmget", "f1", "f2")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
arr := v.([]interface{})
|
|
||||||
if len(arr) != 2 {
|
|
||||||
t.Fatalf("invalid arr %v", arr)
|
|
||||||
}
|
|
||||||
if arr[0].(string) != "v1" {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if arr[1].(string) != "v2" {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHGetallCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hgetallCommand(db, "test_hgetall", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hgetall") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.HSet([]byte("test_hgetall"), []byte("f"), []byte("v"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
v, err := hgetallCommand(db, "test_hgetall")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
m := v.(map[string]string)
|
|
||||||
if m["f"] != "v" {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHKeysCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hkeysCommand(db, "test_hkeys", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hkeys") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
_, err = db.HSet([]byte("test_hkeys"), []byte("f"), []byte("v"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
v, err := hkeysCommand(db, "test_hkeys")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
arr := v.([]string)
|
|
||||||
if arr[0] != "f" {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHClearCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hclearCommand(db, "test_hclear", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hclear") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = db.HSet([]byte("test_hclear"), []byte("f"), []byte("v"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hclearCommand(db, "test_hclear")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHMclearCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hmclearCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hmclear") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hmclearCommand(db, "test_hmclear1", "test_hmclear2")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 2 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHExpireCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hexpireCommand(db, "test_hexpire")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hexpire") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
v, err := hexpireCommand(db, "test_hexpire", "10")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHExpireAtCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hexpireAtCommand(db, "test_hexpireat")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hexpireat") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expireAt := fmt.Sprintf("%d", time.Now().Unix()+10)
|
|
||||||
v, err := hexpireCommand(db, "test_hexpireat", expireAt)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHTTLCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := httlCommand(db, "test_httl", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "httl") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := httlCommand(db, "test_httl")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != -1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHPersistCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := hpersistCommand(db, "test_hpersist", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "hpersist") {
|
|
||||||
t.Fatalf("invalid err %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := hpersistCommand(db, "test_hpersist")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,278 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "get")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.Get(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
if v == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return ledis.String(v), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "set")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
val := []byte(args[1])
|
|
||||||
if err := db.Set(key, val); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return []interface{}{true, MSG_OK}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func getsetCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "getset")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
val := []byte(args[1])
|
|
||||||
if v, err := db.GetSet(key, val); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
if v == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return ledis.String(v), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setnxCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "setnx")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
val := []byte(args[1])
|
|
||||||
if n, err := db.SetNX(key, val); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func existsCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "exists")
|
|
||||||
}
|
|
||||||
|
|
||||||
if n, err := db.Exists([]byte(args[0])); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func incrCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "incr")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.Incr(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func decrCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "decr")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.Decr(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func incrbyCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "incrby")
|
|
||||||
}
|
|
||||||
|
|
||||||
delta, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
if n, err := db.IncryBy(key, delta); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func decrbyCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "decrby")
|
|
||||||
}
|
|
||||||
|
|
||||||
delta, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
if n, err := db.DecrBy(key, delta); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func delCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "del")
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := make([][]byte, len(args))
|
|
||||||
if n, err := db.Del(keys...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func msetCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) == 0 || len(args)%2 != 0 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "mset")
|
|
||||||
}
|
|
||||||
|
|
||||||
kvs := make([]ledis.KVPair, len(args)/2)
|
|
||||||
for i := 0; i < len(kvs); i++ {
|
|
||||||
kvs[i].Key = []byte(args[2*i])
|
|
||||||
kvs[i].Value = []byte(args[2*i+1])
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := db.MSet(kvs...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return []interface{}{true, MSG_OK}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func mgetCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "mget")
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := make([][]byte, len(args))
|
|
||||||
for i, arg := range args {
|
|
||||||
keys[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
if vals, err := db.MGet(keys...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
arr := make([]interface{}, len(vals))
|
|
||||||
for i, v := range vals {
|
|
||||||
if v == nil {
|
|
||||||
arr[i] = nil
|
|
||||||
} else {
|
|
||||||
arr[i] = ledis.String(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arr, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func expireCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "expire")
|
|
||||||
}
|
|
||||||
|
|
||||||
duration, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.Expire(key, duration); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func expireAtCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "expireat")
|
|
||||||
}
|
|
||||||
|
|
||||||
when, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.ExpireAt(key, when); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ttlCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "ttl")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
if v, err := db.TTL(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func persistCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "persist")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
if n, err := db.Persist(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
register("expire", expireCommand)
|
|
||||||
register("expireat", expireAtCommand)
|
|
||||||
register("ttl", ttlCommand)
|
|
||||||
register("persist", persistCommand)
|
|
||||||
}
|
|
|
@ -1,261 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := getCommand(db, "test_get", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "get") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = db.Set([]byte("test_get"), []byte("v"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
v, err := getCommand(db, "test_get")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(string) != "v" {
|
|
||||||
t.Fatalf("invalid result %v", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := setCommand(db, "test_set")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "set") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := setCommand(db, "test_set", "v")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
r := v.([]interface{})
|
|
||||||
if len(r) != 2 {
|
|
||||||
t.Fatalf("invalid result %v", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if r[0].(bool) != true {
|
|
||||||
t.Fatalf("invalid result %v", r[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
if r[1].(string) != "OK" {
|
|
||||||
t.Fatalf("invalid result %v", r[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetsetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := getsetCommand(db, "test_getset")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "getset") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := getsetCommand(db, "test_getset", "v")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v != nil {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetnxCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := setnxCommand(db, "test_setnx")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "setnx") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := setnxCommand(db, "test_setnx", "v")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExistsCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := existsCommand(db, "test_exists", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "exists") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := existsCommand(db, "test_exists")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIncrCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := incrCommand(db, "test_incr", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "incr") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := incrCommand(db, "test_incr")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecrCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := decrCommand(db, "test_decr", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "decr") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := decrCommand(db, "test_decr")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != -1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDelCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := delCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "del") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := delCommand(db, "test_del")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMsetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := msetCommand(db, "a", "b", "c")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "mset") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := msetCommand(db, "test_mset", "v")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
r := v.([]interface{})
|
|
||||||
if len(r) != 2 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
if r[0].(bool) != true {
|
|
||||||
t.Fatal("invalid result ", r[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
if r[1].(string) != "OK" {
|
|
||||||
t.Fatal("invalid result ", r[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMgetCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := mgetCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "mget") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := mgetCommand(db, "test_mget")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
arr := v.([]interface{})
|
|
||||||
if arr[0] != nil {
|
|
||||||
t.Fatal("invalid result ", arr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExpireCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := expireCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "expire") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := expireCommand(db, "test_expire", "10")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExpireAtCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := expireAtCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "expireat") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expireAt := fmt.Sprintf("%d", time.Now().Unix()+10)
|
|
||||||
v, err := expireAtCommand(db, "test_expireat", expireAt)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTTLCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := ttlCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "ttl") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := ttlCommand(db, "test_ttl")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != -1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPersistCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := persistCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "persist") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := persistCommand(db, "test_persist")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func lpushCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lpush")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
elems := make([][]byte, len(args[1:]))
|
|
||||||
for i, arg := range args[1:] {
|
|
||||||
elems[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n, err := db.LPush(key, elems...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func rpushCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "rpush")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
elems := make([][]byte, len(args[1:]))
|
|
||||||
for i, arg := range args[1:] {
|
|
||||||
elems[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
if n, err := db.RPush(key, elems...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lpopCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lpop")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
if v, err := db.LPop(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
if v == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return ledis.String(v), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func rpopCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "rpop")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
if v, err := db.RPop(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
if v == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return ledis.String(v), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func llenCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "llen")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.LLen(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lindexCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lindex")
|
|
||||||
}
|
|
||||||
|
|
||||||
index, err := strconv.ParseInt(args[1], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
if v, err := db.LIndex(key, int32(index)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
if v == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return ledis.String(v), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lrangeCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lrange")
|
|
||||||
}
|
|
||||||
|
|
||||||
start, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
stop, err := strconv.ParseInt(args[2], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if vals, err := db.LRange(key, int32(start), int32(stop)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
arr := make([]interface{}, len(vals))
|
|
||||||
for i, v := range vals {
|
|
||||||
if v == nil {
|
|
||||||
arr[i] = nil
|
|
||||||
} else {
|
|
||||||
arr[i] = ledis.String(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arr, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lclearCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lclear")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.LClear(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lmclearCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lmclear")
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := make([][]byte, len(args))
|
|
||||||
for i, arg := range args {
|
|
||||||
keys[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
if n, err := db.LMclear(keys...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lexpireCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lexpire")
|
|
||||||
}
|
|
||||||
|
|
||||||
duration, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.LExpire(key, duration); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lexpireAtCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lexpireat")
|
|
||||||
}
|
|
||||||
|
|
||||||
when, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.LExpireAt(key, when); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lttlCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lttl")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.LTTL(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lpersistCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "lpersist")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.LPersist(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
register("lindex", lindexCommand)
|
|
||||||
register("llen", llenCommand)
|
|
||||||
register("lpop", lpopCommand)
|
|
||||||
register("lrange", lrangeCommand)
|
|
||||||
register("lpush", lpushCommand)
|
|
||||||
register("rpop", rpopCommand)
|
|
||||||
register("rpush", rpushCommand)
|
|
||||||
|
|
||||||
//ledisdb special command
|
|
||||||
|
|
||||||
register("lclear", lclearCommand)
|
|
||||||
register("lmclear", lmclearCommand)
|
|
||||||
register("lexpire", lexpireCommand)
|
|
||||||
register("lexpireat", lexpireAtCommand)
|
|
||||||
register("lttl", lttlCommand)
|
|
||||||
register("lpersist", lpersistCommand)
|
|
||||||
}
|
|
|
@ -1,217 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestLpushCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lpushCommand(db, "test_lpush")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lpush") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := lpushCommand(db, "test_lpush", "1", "2")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 2 {
|
|
||||||
t.Fatal("invalid result", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRpushCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := rpushCommand(db, "test_rpush")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "rpush") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := rpushCommand(db, "test_rpush", "1", "2")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 2 {
|
|
||||||
t.Fatal("invalid result", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLpopCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lpopCommand(db, "test_lpop", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lpop") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := lpopCommand(db, "test_lpop")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != nil {
|
|
||||||
t.Fatal("invalid result", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRpopCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := rpopCommand(db, "test_rpop", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "rpop") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := rpopCommand(db, "test_lpop")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != nil {
|
|
||||||
t.Fatal("invalid result", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLlenCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := llenCommand(db, "test_llen", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "llen") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := llenCommand(db, "test_llen")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLindexCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lindexCommand(db, "test_lindex")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lindex") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := lindexCommand(db, "test_lindex", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != nil {
|
|
||||||
t.Fatal("invalid result", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLrangeCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lrangeCommand(db, "test_lrange")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lrange") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := lrangeCommand(db, "test_lrange", "1", "2")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
arr := v.([]interface{})
|
|
||||||
if len(arr) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLclearCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lclearCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lclear") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := lclearCommand(db, "test_lclear")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLmclearCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lmclearCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lmclear") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := lmclearCommand(db, "test_lmclear")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLexpireCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lexpireCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lexpire") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := lexpireCommand(db, "test_lexpire", "10")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLexpireAtCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lexpireAtCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lexpireat") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
expireAt := fmt.Sprintf("%d", time.Now().Unix())
|
|
||||||
v, err := lexpireCommand(db, "test_lexpireat", expireAt)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLTTLCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lttlCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lttl") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := lttlCommand(db, "test_lttl")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != -1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLpersistCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := lpersistCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "lpersist") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := lpersistCommand(db, "test_lpersist")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,527 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"math"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var errScoreOverflow = errors.New("zset score overflow")
|
|
||||||
|
|
||||||
func zaddCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zadd")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args[1:])%2 != 0 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zadd")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
args = args[1:]
|
|
||||||
|
|
||||||
params := make([]ledis.ScorePair, len(args)/2)
|
|
||||||
for i := 0; i < len(params); i++ {
|
|
||||||
score, err := strconv.ParseInt(args[2*i], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
params[i].Score = score
|
|
||||||
params[i].Member = []byte(args[2*i+1])
|
|
||||||
}
|
|
||||||
|
|
||||||
if n, err := db.ZAdd(key, params...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zcardCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zcard")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.ZCard(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zscoreCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zscore")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
member := []byte(args[1])
|
|
||||||
|
|
||||||
if s, err := db.ZScore(key, member); err != nil {
|
|
||||||
if err == ledis.ErrScoreMiss {
|
|
||||||
return nil, nil
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return strconv.FormatInt(s, 10), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zremCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zrem")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
members := make([][]byte, len(args[1:]))
|
|
||||||
for i, arg := range args[1:] {
|
|
||||||
members[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
if n, err := db.ZRem(key, members...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zincrbyCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zincrby")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
delta, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
member := []byte(args[2])
|
|
||||||
if v, err := db.ZIncrBy(key, delta, member); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return strconv.FormatInt(v, 10), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zparseScoreRange(minBuf string, maxBuf string) (min int64, max int64, err error) {
|
|
||||||
if strings.ToLower(minBuf) == "-inf" {
|
|
||||||
min = math.MinInt64
|
|
||||||
} else {
|
|
||||||
var lopen bool = false
|
|
||||||
|
|
||||||
if len(minBuf) == 0 {
|
|
||||||
err = ErrValue
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if minBuf[0] == '(' {
|
|
||||||
lopen = true
|
|
||||||
minBuf = minBuf[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
min, err = strconv.ParseInt(minBuf, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
err = ErrValue
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if min <= ledis.MinScore || min >= ledis.MaxScore {
|
|
||||||
err = errScoreOverflow
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if lopen {
|
|
||||||
min++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.ToLower(maxBuf) == "+inf" {
|
|
||||||
max = math.MaxInt64
|
|
||||||
} else {
|
|
||||||
var ropen = false
|
|
||||||
|
|
||||||
if len(maxBuf) == 0 {
|
|
||||||
err = ErrValue
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if maxBuf[0] == '(' {
|
|
||||||
ropen = true
|
|
||||||
maxBuf = maxBuf[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
max, err = strconv.ParseInt(maxBuf, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
err = ErrValue
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if max <= ledis.MinScore || max >= ledis.MaxScore {
|
|
||||||
err = errScoreOverflow
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ropen {
|
|
||||||
max--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func zcountCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zcount")
|
|
||||||
}
|
|
||||||
|
|
||||||
min, max, err := zparseScoreRange(args[1], args[2])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if min > max {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.ZCount(key, min, max); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zrankCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zrank")
|
|
||||||
}
|
|
||||||
key := []byte(args[0])
|
|
||||||
member := []byte(args[1])
|
|
||||||
|
|
||||||
if n, err := db.ZRank(key, member); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if n == -1 {
|
|
||||||
return nil, nil
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zrevrankCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zrevrank")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
member := []byte(args[1])
|
|
||||||
if n, err := db.ZRevRank(key, member); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if n == -1 {
|
|
||||||
return nil, nil
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zremrangebyrankCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zremrangebyrank")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
start, err := strconv.Atoi(args[1])
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
stop, err := strconv.Atoi(args[2])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
if n, err := db.ZRemRangeByRank(key, start, stop); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zremrangebyscoreCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zremrangebyscore")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
min, max, err := zparseScoreRange(args[1], args[2])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if n, err := db.ZRemRangeByScore(key, min, max); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zrangeGeneric(db *ledis.DB, reverse bool, args ...string) (interface{}, error) {
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
start, err := strconv.Atoi(args[1])
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
stop, err := strconv.Atoi(args[2])
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
args = args[3:]
|
|
||||||
var withScores bool = false
|
|
||||||
|
|
||||||
if len(args) > 0 {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, ErrSyntax
|
|
||||||
}
|
|
||||||
if strings.ToLower(args[0]) == "withscores" {
|
|
||||||
withScores = true
|
|
||||||
} else {
|
|
||||||
return nil, ErrSyntax
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if datas, err := db.ZRangeGeneric(key, start, stop, reverse); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return makeScorePairArray(datas, withScores), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeScorePairArray(datas []ledis.ScorePair, withScores bool) []string {
|
|
||||||
var arr []string
|
|
||||||
if withScores {
|
|
||||||
arr = make([]string, 2*len(datas))
|
|
||||||
for i, data := range datas {
|
|
||||||
arr[2*i] = ledis.String(data.Member)
|
|
||||||
arr[2*i+1] = strconv.FormatInt(data.Score, 10)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
arr = make([]string, len(datas))
|
|
||||||
for i, data := range datas {
|
|
||||||
arr[i] = ledis.String(data.Member)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arr
|
|
||||||
}
|
|
||||||
|
|
||||||
func zrangeCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zrange")
|
|
||||||
}
|
|
||||||
return zrangeGeneric(db, false, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func zrevrangeCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zrevrange")
|
|
||||||
}
|
|
||||||
return zrangeGeneric(db, true, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func zrangebyscoreGeneric(db *ledis.DB, reverse bool, args ...string) (interface{}, error) {
|
|
||||||
key := []byte(args[0])
|
|
||||||
|
|
||||||
var minScore, maxScore string
|
|
||||||
|
|
||||||
if !reverse {
|
|
||||||
minScore, maxScore = args[1], args[2]
|
|
||||||
} else {
|
|
||||||
minScore, maxScore = args[2], args[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
min, max, err := zparseScoreRange(minScore, maxScore)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
args = args[3:]
|
|
||||||
|
|
||||||
var withScores bool = false
|
|
||||||
|
|
||||||
if len(args) > 0 && strings.ToLower(args[0]) == "withscores" {
|
|
||||||
withScores = true
|
|
||||||
args = args[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset int = 0
|
|
||||||
var count int = -1
|
|
||||||
|
|
||||||
if len(args) > 0 {
|
|
||||||
if len(args) != 3 {
|
|
||||||
return nil, ErrSyntax
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.ToLower(args[0]) != "limit" {
|
|
||||||
return nil, ErrSyntax
|
|
||||||
}
|
|
||||||
|
|
||||||
if offset, err = strconv.Atoi(args[1]); err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
if count, err = strconv.Atoi(args[2]); err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if offset < 0 {
|
|
||||||
return []interface{}{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if datas, err := db.ZRangeByScoreGeneric(key, min, max, offset, count, reverse); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return makeScorePairArray(datas, withScores), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zrangebyscoreCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zrangebyscore")
|
|
||||||
}
|
|
||||||
return zrangebyscoreGeneric(db, false, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func zrevrangebyscoreCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 3 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zrevrangebyscore")
|
|
||||||
}
|
|
||||||
return zrangebyscoreGeneric(db, true, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func zclearCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zclear")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.ZClear(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zmclearCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zmclear")
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := make([][]byte, len(args))
|
|
||||||
for i, arg := range args {
|
|
||||||
keys[i] = []byte(arg)
|
|
||||||
}
|
|
||||||
if n, err := db.ZMclear(keys...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zexpireCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zexpire")
|
|
||||||
}
|
|
||||||
|
|
||||||
duration, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.ZExpire(key, duration); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zexpireAtCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 2 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zexpireat")
|
|
||||||
}
|
|
||||||
|
|
||||||
when, err := strconv.ParseInt(args[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrValue
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.ZExpireAt(key, when); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zttlCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zttl")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if v, err := db.ZTTL(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func zpersistCommand(db *ledis.DB, args ...string) (interface{}, error) {
|
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, fmt.Errorf(ERR_ARGUMENT_FORMAT, "zpersist")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(args[0])
|
|
||||||
if n, err := db.ZPersist(key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
register("zadd", zaddCommand)
|
|
||||||
register("zcard", zcardCommand)
|
|
||||||
register("zcount", zcountCommand)
|
|
||||||
register("zincrby", zincrbyCommand)
|
|
||||||
register("zrange", zrangeCommand)
|
|
||||||
register("zrangebyscore", zrangebyscoreCommand)
|
|
||||||
register("zrank", zrankCommand)
|
|
||||||
register("zrem", zremCommand)
|
|
||||||
register("zremrangebyrank", zremrangebyrankCommand)
|
|
||||||
register("zremrangebyscore", zremrangebyscoreCommand)
|
|
||||||
register("zrevrange", zrevrangeCommand)
|
|
||||||
register("zrevrank", zrevrankCommand)
|
|
||||||
register("zrevrangebyscore", zrevrangebyscoreCommand)
|
|
||||||
register("zscore", zscoreCommand)
|
|
||||||
|
|
||||||
//ledisdb special command
|
|
||||||
|
|
||||||
register("zclear", zclearCommand)
|
|
||||||
register("zmclear", zmclearCommand)
|
|
||||||
register("zexpire", zexpireCommand)
|
|
||||||
register("zexpireat", zexpireAtCommand)
|
|
||||||
register("zttl", zttlCommand)
|
|
||||||
register("zpersist", zpersistCommand)
|
|
||||||
}
|
|
|
@ -1,299 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestZAddCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zaddCommand(db, "test_zadd")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zadd") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := zaddCommand(db, "test_zadd", "10", "m")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZCardCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zcardCommand(db, "test_zcard", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zcard") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := zcardCommand(db, "test_zcard")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZScore(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zscoreCommand(db, "test_zscore")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zscore") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zscoreCommand(db, "test_zscore", "m")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != nil {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZRemCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zremCommand(db, "test_zrem")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zrem") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zremCommand(db, "test_zrem", "m")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZIncrbyCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zincrbyCommand(db, "test_zincrby")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zincrby") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zincrbyCommand(db, "test_zincrby", "10", "m")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(string) != "10" {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZCountCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zcountCommand(db, "test_zcount")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zcount") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zcountCommand(db, "test_zcount", "0", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZRankCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zrankCommand(db, "test_zrank")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zrank") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zrankCommand(db, "test_zcount", "m")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != nil {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZRevrankCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zrevrankCommand(db, "test_zrevrank")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zrevrank") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zrevrankCommand(db, "test_zrevrank", "m")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != nil {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZRemrangebyrankCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zremrangebyrankCommand(db, "test_zremrangebyrank")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zremrangebyrank") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zremrangebyrankCommand(db, "test_zremrangebyrank", "0", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZRemrangebyscore(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zremrangebyscoreCommand(db, "test_zremrangebyscore")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zremrangebyscore") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zremrangebyscoreCommand(db, "test_zremrangebyscore", "0", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZRangeCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zrangeCommand(db, "test_zrange")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zrange") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zrangeCommand(db, "test_zrange", "0", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v.([]string)) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZRangebyscoreCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zrangebyscoreCommand(db, "test_zrangebyscore")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zrangebyscore") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zrangebyscoreCommand(db, "test_zrangebyscore", "0", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v.([]string)) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZRevrangebyscoreCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zrevrangebyscoreCommand(db, "test_zrevrangebyscore")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zrevrangebyscore") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zrevrangebyscoreCommand(db, "test_zrevrangebyscore", "0", "1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v.([]string)) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZMclearCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zmclearCommand(db)
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zmclear") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zmclearCommand(db, "test_zmclear")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZExpireCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zexpireCommand(db, "test_zexpire")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zexpire") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zexpireCommand(db, "test_zexpire", "10")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZExpireAtCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zexpireAtCommand(db, "test_zexpireat")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zexpireat") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
expireAt := fmt.Sprintf("%d", time.Now().Unix()+10)
|
|
||||||
v, err := zexpireAtCommand(db, "test_zexpire", expireAt)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZTTLCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zttlCommand(db, "test_zttl", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zttl") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zttlCommand(db, "test_zttl")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != -1 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZPersistCommand(t *testing.T) {
|
|
||||||
db := getTestDB()
|
|
||||||
_, err := zpersistCommand(db, "test_zpersist", "a")
|
|
||||||
if err == nil || err.Error() != fmt.Sprintf(ERR_ARGUMENT_FORMAT, "zpersist") {
|
|
||||||
t.Fatal("invalid err ", err)
|
|
||||||
}
|
|
||||||
v, err := zpersistCommand(db, "test_zpersist")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.(int64) != 0 {
|
|
||||||
t.Fatal("invalid result ", v)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,156 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
//"github.com/siddontang/go-websocket/websocket"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"github.com/siddontang/go-log/log"
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"github.com/ugorji/go/codec"
|
|
||||||
"gopkg.in/mgo.v2/bson"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CmdHandler struct {
|
|
||||||
Ldb *ledis.Ledis
|
|
||||||
}
|
|
||||||
|
|
||||||
var allowedContentTypes = map[string]struct{}{
|
|
||||||
"json": struct{}{},
|
|
||||||
"bson": struct{}{},
|
|
||||||
"msgpack": struct{}{},
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *CmdHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.URL.Path == "/" {
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
idx, cmd, args := h.parseReqPath(r.URL.Path)
|
|
||||||
|
|
||||||
contentType := r.FormValue("type")
|
|
||||||
if contentType == "" {
|
|
||||||
contentType = "json"
|
|
||||||
}
|
|
||||||
contentType = strings.ToLower(contentType)
|
|
||||||
if _, ok := allowedContentTypes[contentType]; !ok {
|
|
||||||
h.writeError(
|
|
||||||
cmd,
|
|
||||||
fmt.Errorf("unsupported content type '%s', only json, bson, msgpack are supported", contentType),
|
|
||||||
w,
|
|
||||||
"json")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cmdFunc := lookup(cmd)
|
|
||||||
if cmdFunc == nil {
|
|
||||||
h.cmdNotFound(cmd, w, contentType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var db *ledis.DB
|
|
||||||
var err error
|
|
||||||
if db, err = h.Ldb.Select(idx); err != nil {
|
|
||||||
h.writeError(cmd, err, w, contentType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result, err := cmdFunc(db, args...)
|
|
||||||
if err != nil {
|
|
||||||
h.writeError(cmd, err, w, contentType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.write(cmd, result, w, contentType)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *CmdHandler) parseReqPath(path string) (db int, cmd string, args []string) {
|
|
||||||
/*
|
|
||||||
this function extracts `db`, `cmd` and `args` from `path`
|
|
||||||
the proper format of `path` is /cmd/arg1/arg2/../argN or /db/cmd/arg1/arg2/../argN
|
|
||||||
if `path` is the first kind, `db` will be 0
|
|
||||||
*/
|
|
||||||
substrings := strings.Split(strings.TrimLeft(path, "/"), "/")
|
|
||||||
if len(substrings) == 1 {
|
|
||||||
return 0, substrings[0], substrings[1:]
|
|
||||||
}
|
|
||||||
db, err := strconv.Atoi(substrings[0])
|
|
||||||
if err != nil {
|
|
||||||
cmd = substrings[0]
|
|
||||||
args = substrings[1:]
|
|
||||||
} else {
|
|
||||||
cmd = substrings[1]
|
|
||||||
args = substrings[2:]
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (h *CmdHandler) cmdNotFound(cmd string, w http.ResponseWriter, contentType string) {
|
|
||||||
err := fmt.Errorf("unknown command '%s'", cmd)
|
|
||||||
h.writeError(cmd, err, w, contentType)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *CmdHandler) write(cmd string, result interface{}, w http.ResponseWriter, contentType string) {
|
|
||||||
m := map[string]interface{}{
|
|
||||||
cmd: result,
|
|
||||||
}
|
|
||||||
|
|
||||||
switch contentType {
|
|
||||||
case "json":
|
|
||||||
writeJSON(&m, w)
|
|
||||||
case "bson":
|
|
||||||
writeBSON(&m, w)
|
|
||||||
case "msgpack":
|
|
||||||
writeMsgPack(&m, w)
|
|
||||||
default:
|
|
||||||
log.Error("invalid content type %s", contentType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *CmdHandler) writeError(cmd string, err error, w http.ResponseWriter, contentType string) {
|
|
||||||
result := [2]interface{}{
|
|
||||||
false,
|
|
||||||
fmt.Sprintf("ERR %s", err.Error()),
|
|
||||||
}
|
|
||||||
h.write(cmd, result, w, contentType)
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeJSON(resutl interface{}, w http.ResponseWriter) {
|
|
||||||
buf, err := json.Marshal(resutl)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Content-type", "application/json; charset=utf-8")
|
|
||||||
w.Header().Set("Content-Length", strconv.Itoa(len(buf)))
|
|
||||||
|
|
||||||
_, err = w.Write(buf)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeBSON(result interface{}, w http.ResponseWriter) {
|
|
||||||
buf, err := bson.Marshal(result)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Content-type", "application/octet-stream")
|
|
||||||
w.Header().Set("Content-Length", strconv.Itoa(len(buf)))
|
|
||||||
|
|
||||||
_, err = w.Write(buf)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeMsgPack(result interface{}, w http.ResponseWriter) {
|
|
||||||
w.Header().Set("Content-type", "application/octet-stream")
|
|
||||||
|
|
||||||
var mh codec.MsgpackHandle
|
|
||||||
enc := codec.NewEncoder(w, &mh)
|
|
||||||
if err := enc.Encode(result); err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/siddontang/ledisdb/ledis"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
type httpContext struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type httpReader struct {
|
|
||||||
req *http.Request
|
|
||||||
}
|
|
||||||
|
|
||||||
type httpWriter struct {
|
|
||||||
resp *http.ResponseWriter
|
|
||||||
}
|
|
||||||
|
|
||||||
// http context
|
|
||||||
|
|
||||||
func newHttpContext() *httpContext {
|
|
||||||
ctx := new(httpContext)
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *httpContext) addr() string {
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *httpContext) release() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// http reader
|
|
||||||
|
|
||||||
func newHttpReader(req *http.Request) *httpReader {
|
|
||||||
r := new(httpReader)
|
|
||||||
r.req = req
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *httpReader) read() ([][]byte, error) {
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// http writer
|
|
||||||
|
|
||||||
func newHttpWriter(resp *http.ResponseWriter) *httpWriter {
|
|
||||||
w := new(httpWriter)
|
|
||||||
w.resp = resp
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeError(err error) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeStatus(status string) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeInteger(n int64) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeBulk(b []byte) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeArray(lst []interface{}) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeSliceArray(lst [][]byte) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeFVPairArray(lst []ledis.FVPair) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeScorePairArray(lst []ledis.ScorePair, withScores bool) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) writeBulkFrom(n int64, rb io.Reader) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *httpWriter) flush() {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
##HTTP Interface
|
|
||||||
LedisDB provides http interfaces for most commands.
|
|
||||||
####Request
|
|
||||||
The proper url format is
|
|
||||||
|
|
||||||
http://host:port[/db]/cmd/arg1/arg2/.../argN[?type=type]
|
|
||||||
|
|
||||||
'db' and 'type' are optional. 'db' stands for ledis db index, ranges from 0 to 15, its default value is 0. 'type' is a custom content type, can be json, bson or msgpack, json is default.
|
|
||||||
|
|
||||||
|
|
||||||
####Response
|
|
||||||
|
|
||||||
The response format is
|
|
||||||
|
|
||||||
{ cmd: return_value }
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
{ cmd: [success, message] }
|
|
||||||
|
|
||||||
'return_value' stands for the output of 'cmd', it can be a number, a string, a list, or a hash. If the return value is just a descriptive message, the second format will be taken, and 'success', a boolean value, indicates whether it is successful.
|
|
||||||
|
|
||||||
####Example
|
|
||||||
#####Curl
|
|
||||||
|
|
||||||
curl http://127.0.0.1:11181/SET/hello/world
|
|
||||||
→ {"SET":[true,"OK"]}
|
|
||||||
|
|
||||||
curl http://127.0.0.1:11181/0/GET/hello?type=json
|
|
||||||
→ {"GET":"world"}
|
|
||||||
|
|
||||||
#####Python
|
|
||||||
Requires [msgpack-python](https://pypi.python.org/pypi/msgpack-python) and [requests](https://pypi.python.org/pypi/requests/)
|
|
||||||
|
|
||||||
>>> import requests
|
|
||||||
>>> import msgpack
|
|
||||||
|
|
||||||
>>> requests.get("http://127.0.0.1:11181/0/SET/hello/world")
|
|
||||||
>>> r = requests.get("http://127.0.0.1:11181/0/GET/hello?type=msgpack")
|
|
||||||
>>> msgpack.unpackb(r.content)
|
|
||||||
>>> {"GET":"world"}
|
|
||||||
|
|
Loading…
Reference in New Issue