コード例 #1
0
ファイル: cmd_replication.go プロジェクト: JREAMLU/ledisdb
func slaveofCommand(req *requestContext) error {
	args := req.args

	if len(args) != 2 {
		return ErrCmdParams
	}

	masterAddr := ""

	if strings.ToLower(ledis.String(args[0])) == "no" &&
		strings.ToLower(ledis.String(args[1])) == "one" {
		//stop replication, use master = ""
	} else {
		if _, err := strconv.ParseInt(ledis.String(args[1]), 10, 16); err != nil {
			return err
		}

		masterAddr = fmt.Sprintf("%s:%s", args[0], args[1])
	}

	if err := req.app.slaveof(masterAddr); err != nil {
		return err
	}

	req.resp.writeStatus(OK)

	return nil
}
コード例 #2
0
ファイル: client_http.go プロジェクト: huanshi/ledisdb
func (w *httpWriter) writeFVPairArray(lst []ledis.FVPair) {
	m := make(map[string]string)
	for _, elem := range lst {
		m[ledis.String(elem.Field)] = ledis.String(elem.Value)
	}
	w.genericWrite(m)
}
コード例 #3
0
ファイル: cmd_zset.go プロジェクト: rchunping/ledisdb
func zrangebyscoreGeneric(c *client, reverse bool) error {
	args := c.args
	if len(args) < 3 {
		return ErrCmdParams
	}

	key := args[0]
	min, max, err := zparseScoreRange(args[1], args[2])
	if err != nil {
		return err
	}

	args = args[3:]

	var withScores bool = false

	if len(args) > 0 && strings.ToLower(ledis.String(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 ErrCmdParams
		}

		if strings.ToLower(ledis.String(args[0])) != "limit" {
			return ErrCmdParams
		}

		if offset, err = strconv.Atoi(ledis.String(args[1])); err != nil {
			return ErrCmdParams
		}

		if count, err = strconv.Atoi(ledis.String(args[2])); err != nil {
			return ErrCmdParams
		}
	}

	if offset < 0 {
		//for redis, if offset < 0, a empty will return
		//so here we directly return a empty array
		c.writeArray([]interface{}{})
		return nil
	}

	if v, err := c.db.ZRangeByScoreGeneric(key, min, max, withScores, offset, count, reverse); err != nil {
		return err
	} else {
		c.writeArray(v)
	}

	return nil
}
コード例 #4
0
ファイル: cmd_zset.go プロジェクト: Gohan/ledisdb
func zparseRange(c *client, a1 []byte, a2 []byte) (start int, stop int, err error) {
	if start, err = strconv.Atoi(ledis.String(a1)); err != nil {
		return
	}

	if stop, err = strconv.Atoi(ledis.String(a2)); err != nil {
		return
	}

	return
}
コード例 #5
0
ファイル: client_resp.go プロジェクト: Abioy/ledisdb
//A client sends to the Redis server a RESP Array consisting of just Bulk Strings.
func (c *respClient) readRequest() ([][]byte, error) {
	l, err := c.readLine()
	if err != nil {
		return nil, err
	} else if len(l) == 0 || l[0] != '*' {
		return nil, errReadRequest
	}

	var nparams int
	if nparams, err = strconv.Atoi(ledis.String(l[1:])); err != nil {
		return nil, err
	} else if nparams <= 0 {
		return nil, errReadRequest
	}

	req := make([][]byte, 0, nparams)
	var n int
	for i := 0; i < nparams; i++ {
		if l, err = c.readLine(); err != nil {
			return nil, err
		}

		if len(l) == 0 {
			return nil, errReadRequest
		} else if l[0] == '$' {
			//handle resp string
			if n, err = strconv.Atoi(ledis.String(l[1:])); err != nil {
				return nil, err
			} else if n == -1 {
				req = append(req, nil)
			} else {
				buf := make([]byte, n)
				if _, err = io.ReadFull(c.rb, buf); err != nil {
					return nil, err
				}

				if l, err = c.readLine(); err != nil {
					return nil, err
				} else if len(l) != 0 {
					return nil, errors.New("bad bulk string format")
				}

				req = append(req, buf)

			}

		} else {
			return nil, errReadRequest
		}
	}

	return req, nil
}
コード例 #6
0
ファイル: script.go プロジェクト: Abioy/ledisdb
func (w *luaWriter) writeFVPairArray(lst []ledis.FVPair) {
	if lst == nil {
		w.l.PushBoolean(false)
		return
	}

	w.l.CreateTable(len(lst)*2, 0)
	for i, v := range lst {
		w.l.PushString(ledis.String(v.Field))
		w.l.RawSeti(-2, 2*i+1)

		w.l.PushString(ledis.String(v.Value))
		w.l.RawSeti(-2, 2*i+2)
	}
}
コード例 #7
0
ファイル: cmd_zset.go プロジェクト: JREAMLU/ledisdb
func zrangeGeneric(req *requestContext, reverse bool) error {
	args := req.args
	if len(args) < 3 {
		return ErrCmdParams
	}

	key := args[0]

	start, stop, err := zparseRange(req, args[1], args[2])
	if err != nil {
		return ErrValue
	}

	args = args[3:]
	var withScores bool = false

	if len(args) > 0 {
		if len(args) != 1 {
			return ErrCmdParams
		}
		if strings.ToLower(ledis.String(args[0])) == "withscores" {
			withScores = true
		} else {
			return ErrSyntax
		}
	}

	if datas, err := req.db.ZRangeGeneric(key, start, stop, reverse); err != nil {
		return err
	} else {
		req.resp.writeScorePairArray(datas, withScores)
	}
	return nil
}
コード例 #8
0
ファイル: client_resp.go プロジェクト: JREAMLU/ledisdb
func (c *respClient) handleRequest(reqData [][]byte) {
	req := c.req

	if len(reqData) == 0 {
		c.req.cmd = ""
		c.req.args = reqData[0:0]
	} else {
		c.req.cmd = strings.ToLower(ledis.String(reqData[0]))
		c.req.args = reqData[1:]
	}
	if c.req.cmd == "quit" {
		c.req.resp.writeStatus(OK)
		c.req.resp.flush()
		c.conn.Close()
		return
	}

	req.db = c.db

	c.req.perform()

	c.db = req.db // "SELECT"

	return
}
コード例 #9
0
ファイル: cmd_script.go プロジェクト: Abioy/ledisdb
func scriptCommand(c *client) error {
	s := c.app.s
	l := s.l

	s.Lock()

	base := l.GetTop()

	defer func() {
		l.SetTop(base)
		s.Unlock()
	}()

	args := c.args

	if len(args) < 1 {
		return ErrCmdParams
	}

	switch strings.ToLower(ledis.String(args[0])) {
	case "load":
		return scriptLoadCommand(c)
	case "exists":
		return scriptExistsCommand(c)
	case "flush":
		return scriptFlushCommand(c)
	default:
		return fmt.Errorf("invalid script %s", args[0])
	}

	return nil
}
コード例 #10
0
ファイル: util.go プロジェクト: Eddie0330/ledisdb
func ReadBulkTo(rb *bufio.Reader, w io.Writer) error {
	l, err := ReadLine(rb)
	if len(l) == 0 {
		return errBulkFormat
	} else if l[0] == '$' {
		var n int
		//handle resp string
		if n, err = strconv.Atoi(ledis.String(l[1:])); err != nil {
			return err
		} else if n == -1 {
			return nil
		} else {
			if _, err = io.CopyN(w, rb, int64(n)); err != nil {
				return err
			}

			if l, err = ReadLine(rb); err != nil {
				return err
			} else if len(l) != 0 {
				return errBulkFormat
			}
		}
	} else {
		return errBulkFormat
	}

	return nil
}
コード例 #11
0
ファイル: cmd_bit.go プロジェクト: JREAMLU/ledisdb
func boptCommand(req *requestContext) error {
	args := req.args
	if len(args) < 2 {
		return ErrCmdParams
	}

	opDesc := strings.ToLower(ledis.String(args[0]))
	dstKey := args[1]
	srcKeys := args[2:]

	var op uint8
	switch opDesc {
	case "and":
		op = ledis.OPand
	case "or":
		op = ledis.OPor
	case "xor":
		op = ledis.OPxor
	case "not":
		op = ledis.OPnot
	default:
		return ErrCmdParams
	}

	if len(srcKeys) == 0 {
		return ErrCmdParams
	}
	if blen, err := req.db.BOperation(op, dstKey, srcKeys...); err != nil {
		return err
	} else {
		req.resp.writeInteger(int64(blen))
	}
	return nil
}
コード例 #12
0
ファイル: command.go プロジェクト: Abioy/ledisdb
func selectCommand(c *client) error {
	if len(c.args) != 1 {
		return ErrCmdParams
	}

	if index, err := strconv.Atoi(ledis.String(c.args[0])); err != nil {
		return err
	} else {
		if c.db.IsTransaction() {
			if err := c.tx.Select(index); err != nil {
				return err
			} else {
				c.db = c.tx.DB
			}
		} else if c.db.IsInMulti() {
			if err := c.script.Select(index); err != nil {
				return err
			} else {
				c.db = c.script.DB
			}
		} else {
			if db, err := c.ldb.Select(index); err != nil {
				return err
			} else {
				c.db = db
			}
		}
		c.resp.writeStatus(OK)
	}

	return nil
}
コード例 #13
0
ファイル: script.go プロジェクト: Abioy/ledisdb
func (w *luaWriter) writeBulk(b []byte) {
	if b == nil {
		w.l.PushBoolean(false)
	} else {
		w.l.PushString(ledis.String(b))
	}
}
コード例 #14
0
ファイル: cmd_script.go プロジェクト: Abioy/ledisdb
func scriptLoadCommand(c *client) error {
	s := c.app.s
	l := s.l

	if len(c.args) != 2 {
		return ErrCmdParams
	}

	h := sha1.Sum(c.args[1])
	key := hex.EncodeToString(h[0:20])

	if r := l.LoadString(ledis.String(c.args[1])); r != 0 {
		err := fmt.Errorf("%s", l.ToString(-1))
		l.Pop(1)
		return err
	} else {
		l.PushValue(-1)
		l.SetGlobal(key)

		s.chunks[key] = struct{}{}
	}

	c.resp.writeBulk(ledis.Slice(key))
	return nil
}
コード例 #15
0
ファイル: client_http.go プロジェクト: huanshi/ledisdb
func (w *httpWriter) writeScorePairArray(lst []ledis.ScorePair, withScores bool) {
	var arr []string
	if withScores {
		arr = make([]string, 2*len(lst))
		for i, data := range lst {
			arr[2*i] = ledis.String(data.Member)
			arr[2*i+1] = strconv.FormatInt(data.Score, 10)
		}
	} else {
		arr = make([]string, len(lst))
		for i, data := range lst {
			arr[i] = ledis.String(data.Member)
		}
	}
	w.genericWrite(arr)
}
コード例 #16
0
ファイル: cmd_zset.go プロジェクト: Gohan/ledisdb
func zrangeGeneric(c *client, reverse bool) error {
	args := c.args
	if len(args) < 3 {
		return ErrCmdParams
	}

	key := args[0]

	start, stop, err := zparseRange(c, args[1], args[2])
	if err != nil {
		return err
	}

	args = args[3:]
	var withScores bool = false

	if len(args) > 0 && strings.ToLower(ledis.String(args[0])) == "withscores" {
		withScores = true
	}

	if datas, err := c.db.ZRangeGeneric(key, start, stop, reverse); err != nil {
		return err
	} else {
		c.writeScorePairArray(datas, withScores)
	}
	return nil
}
コード例 #17
0
ファイル: client_http.go プロジェクト: huanshi/ledisdb
func (w *httpWriter) writeBulk(b []byte) {
	if b == nil {
		w.genericWrite(nil)
	} else {
		w.genericWrite(ledis.String(b))
	}
}
コード例 #18
0
ファイル: client.go プロジェクト: rchunping/ledisdb
func (c *client) handleRequest(req [][]byte) {
	var err error

	if len(req) == 0 {
		err = ErrEmptyCommand
	} else {
		c.cmd = strings.ToLower(ledis.String(req[0]))
		c.args = req[1:]

		f, ok := regCmds[c.cmd]
		if !ok {
			err = ErrNotFound
		} else {
			go func() {
				c.reqC <- f(c)
			}()
			err = <-c.reqC
		}
	}

	if err != nil {
		c.writeError(err)
	}

	c.wb.Flush()
}
コード例 #19
0
ファイル: script.go プロジェクト: Abioy/ledisdb
func luaSetGlobalArray(l *lua.State, name string, ay [][]byte) {
	l.NewTable()

	for i := 0; i < len(ay); i++ {
		l.PushString(ledis.String(ay[i]))
		l.RawSeti(-2, i+1)
	}

	l.SetGlobal(name)
}
コード例 #20
0
ファイル: client_http.go プロジェクト: huanshi/ledisdb
func (w *httpWriter) writeSliceArray(lst [][]byte) {
	arr := make([]interface{}, len(lst))
	for i, elem := range lst {
		if elem == nil {
			arr[i] = nil
		} else {
			arr[i] = ledis.String(elem)
		}
	}
	w.genericWrite(arr)
}
コード例 #21
0
ファイル: script.go プロジェクト: Abioy/ledisdb
func (w *luaWriter) writeSliceArray(lst [][]byte) {
	if lst == nil {
		w.l.PushBoolean(false)
		return
	}

	w.l.CreateTable(len(lst), 0)
	for i, v := range lst {
		w.l.PushString(ledis.String(v))
		w.l.RawSeti(-2, i+1)
	}
}
コード例 #22
0
ファイル: command.go プロジェクト: Abioy/ledisdb
func infoCommand(c *client) error {
	if len(c.args) > 1 {
		return ErrSyntax
	}
	var section string
	if len(c.args) == 1 {
		section = strings.ToLower(ledis.String(c.args[0]))
	}

	buf := c.app.info.Dump(section)
	c.resp.writeBulk(buf)

	return nil
}
コード例 #23
0
ファイル: script.go プロジェクト: Abioy/ledisdb
func (w *luaWriter) writeScorePairArray(lst []ledis.ScorePair, withScores bool) {
	if lst == nil {
		w.l.PushBoolean(false)
		return
	}

	if withScores {
		w.l.CreateTable(len(lst)*2, 0)
		for i, v := range lst {
			w.l.PushString(ledis.String(v.Member))
			w.l.RawSeti(-2, 2*i+1)

			w.l.PushString(ledis.String(ledis.StrPutInt64(v.Score)))
			w.l.RawSeti(-2, 2*i+2)
		}
	} else {
		w.l.CreateTable(len(lst), 0)
		for i, v := range lst {
			w.l.PushString(ledis.String(v.Member))
			w.l.RawSeti(-2, i+1)
		}
	}
}
コード例 #24
0
ファイル: client.go プロジェクト: nzinfo/ledisdb
func (c *client) handleRequest(req [][]byte) {
	var err error

	start := time.Now()

	if len(req) == 0 {
		err = ErrEmptyCommand
	} else {
		c.cmd = strings.ToLower(ledis.String(req[0]))
		c.args = req[1:]

		f, ok := regCmds[c.cmd]
		if !ok {
			err = ErrNotFound
		} else {
			go func() {
				c.reqC <- f(c)
			}()
			err = <-c.reqC
		}
	}

	duration := time.Since(start)

	if c.app.access != nil {
		c.logBuf.Reset()
		for i, r := range req {
			left := 256 - c.logBuf.Len()
			if left <= 0 {
				break
			} else if len(r) <= left {
				c.logBuf.Write(r)
				if i != len(req)-1 {
					c.logBuf.WriteByte(' ')
				}
			} else {
				c.logBuf.Write(r[0:left])
			}
		}

		c.app.access.Log(c.c.RemoteAddr().String(), duration.Nanoseconds()/1000000, c.logBuf.Bytes(), err)
	}

	if err != nil {
		c.writeError(err)
	}

	c.wb.Flush()
}
コード例 #25
0
ファイル: command.go プロジェクト: JREAMLU/ledisdb
func selectCommand(req *requestContext) error {
	if len(req.args) != 1 {
		return ErrCmdParams
	}

	if index, err := strconv.Atoi(ledis.String(req.args[0])); err != nil {
		return err
	} else {
		if db, err := req.ldb.Select(index); err != nil {
			return err
		} else {
			req.db = db
			req.resp.writeStatus(OK)
		}
	}
	return nil
}
コード例 #26
0
ファイル: command.go プロジェクト: Eddie0330/ledisdb
func selectCommand(c *client) error {
	if len(c.args) != 1 {
		return ErrCmdParams
	}

	if index, err := strconv.Atoi(ledis.String(c.args[0])); err != nil {
		return err
	} else {
		if db, err := c.ldb.Select(index); err != nil {
			return err
		} else {
			c.db = db
			c.writeStatus(OK)
		}
	}
	return nil
}
コード例 #27
0
ファイル: cmd_script.go プロジェクト: Abioy/ledisdb
func scriptExistsCommand(c *client) error {
	s := c.app.s

	if len(c.args) < 2 {
		return ErrCmdParams
	}

	ay := make([]interface{}, len(c.args[1:]))
	for i, n := range c.args[1:] {
		if _, ok := s.chunks[ledis.String(n)]; ok {
			ay[i] = int64(1)
		} else {
			ay[i] = int64(0)
		}
	}

	c.resp.writeArray(ay)
	return nil
}
コード例 #28
0
ファイル: cmd_kv.go プロジェクト: Abioy/ledisdb
func parseScanArgs(c *client) (key []byte, match string, count int, err error) {
	args := c.args
	count = 10

	switch len(args) {
	case 0:
		key = nil
		return
	case 1, 3, 5:
		key = args[0]
		break
	default:
		err = ErrCmdParams
		return
	}

	if len(args) == 3 {
		switch strings.ToLower(ledis.String(args[1])) {
		case "match":
			match = ledis.String(args[2])
			return
		case "count":
			count, err = strconv.Atoi(ledis.String(args[2]))
			return
		default:
			err = ErrCmdParams
			return
		}
	} else if len(args) == 5 {
		if strings.ToLower(ledis.String(args[1])) != "match" {
			err = ErrCmdParams
			return
		} else if strings.ToLower(ledis.String(args[3])) != "count" {
			err = ErrCmdParams
			return
		}

		match = ledis.String(args[2])
		count, err = strconv.Atoi(ledis.String(args[4]))
		return
	}

	return
}
コード例 #29
0
ファイル: cmd_script.go プロジェクト: Abioy/ledisdb
func parseEvalArgs(l *lua.State, c *client) error {
	args := c.args
	if len(args) < 2 {
		return ErrCmdParams
	}

	args = args[1:]

	n, err := strconv.Atoi(ledis.String(args[0]))
	if err != nil {
		return err
	}

	if n > len(args)-1 {
		return ErrCmdParams
	}

	luaSetGlobalArray(l, "KEYS", args[1:n+1])
	luaSetGlobalArray(l, "ARGV", args[n+1:])

	return nil
}
コード例 #30
0
ファイル: cmd_zset.go プロジェクト: Gohan/ledisdb
func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err error) {
	if strings.ToLower(ledis.String(minBuf)) == "-inf" {
		min = math.MinInt64
	} else {
		var lopen bool = false
		if minBuf[0] == '(' {
			lopen = true
			minBuf = minBuf[1:]
		}

		if len(minBuf) == 0 {
			err = ErrCmdParams
			return
		}

		min, err = ledis.StrInt64(minBuf, nil)
		if err != nil {
			return
		}

		if min <= ledis.MinScore || min >= ledis.MaxScore {
			err = errScoreOverflow
			return
		}

		if lopen {
			min++
		}
	}

	if strings.ToLower(ledis.String(maxBuf)) == "+inf" {
		max = math.MaxInt64
	} else {
		var ropen = false
		if maxBuf[0] == '(' {
			ropen = true
			maxBuf = maxBuf[1:]
		}

		if len(maxBuf) == 0 {
			err = ErrCmdParams
			return
		}

		max, err = ledis.StrInt64(maxBuf, nil)
		if err != nil {
			return
		}

		if max <= ledis.MinScore || max >= ledis.MaxScore {
			err = errScoreOverflow
			return
		}

		if ropen {
			max--
		}
	}

	return
}