Пример #1
0
func lrangeCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	var start int64
	var stop int64
	var err error

	start, err = strconv.ParseInt(hack.String(args[1]), 10, 64)
	if err != nil {
		return err
	}

	stop, err = strconv.ParseInt(hack.String(args[2]), 10, 64)
	if err != nil {
		return err
	}

	if v, err := c.app.list_range(args[0], int32(start), int32(stop)); err != nil {
		return err
	} else {
		c.writeArray(v)
	}

	return nil
}
Пример #2
0
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(hack.String(args[0])) == "withscores" {
		withScores = true
		args = args[1:]
	}

	var offset int = 0
	var limit int = -1

	if len(args) > 0 {
		if len(args) != 3 {
			return ErrCmdParams
		}

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

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

		if limit, err = strconv.Atoi(hack.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.app.zset_range(key, min, max, withScores, offset, limit, reverse); err != nil {
		return err
	} else {
		c.writeArray(v)
	}

	return nil
}
Пример #3
0
//A client sends to the Redis server a RESP Array consisting of just Bulk Strings.
func (c *client) 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(hack.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(hack.String(l[1:])); err != nil {
				return nil, err
			} else if n == -1 {
				req = append(req, nil)
			} else {
				buf := make([]byte, n+2)
				if _, err = io.ReadFull(c.rb, buf); err != nil {
					return nil, err
				} else if buf[len(buf)-2] != '\r' || buf[len(buf)-1] != '\n' {
					return nil, errReadRequest

				} else {
					req = append(req, buf[0:len(buf)-2])
				}
			}

		} else {
			return nil, errReadRequest
		}
	}

	return req, nil
}
Пример #4
0
func (a *App) hash_incrby(key []byte, field []byte, delta int64) (int64, error) {
	t := a.hashTx
	t.Lock()
	defer t.Unlock()

	ek := encode_hash_key(key, field)

	var n int64 = 0
	v, err := a.db.Get(ek)
	if err != nil {
		return 0, err
	} else if v != nil {
		if n, err = strconv.ParseInt(hack.String(v), 10, 64); err != nil {
			return 0, err
		}
	}

	n += delta

	_, err = a.hash_setItem(key, field, hack.Slice(strconv.FormatInt(n, 10)))
	if err != nil {
		return 0, err
	}

	err = t.Commit()

	return n, err
}
Пример #5
0
func zrangeGeneric(c *client, reverse bool) error {
	args := c.args
	if len(args) < 3 {
		return ErrCmdParams
	}

	key := args[0]

	offset, limit, err := zparseRange(c, key, args[1], args[2])
	if err != nil {
		return err
	}

	if offset < 0 {
		c.writeArray([]interface{}{})
		return nil
	}

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

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

	if v, err := c.app.zset_range(key, MinScore, MaxScore, withScores, offset, limit, reverse); err != nil {
		return err
	} else {
		c.writeArray(v)
	}
	return nil
}
Пример #6
0
func zaddCommand(c *client) error {
	args := c.args
	if len(args) < 3 {
		return ErrCmdParams
	}

	key := args[0]
	if len(args[1:])%2 != 0 {
		return ErrCmdParams
	}

	args = args[1:]
	params := make([]interface{}, len(args))
	for i := 0; i < len(params); i += 2 {
		score, err := strconv.ParseInt(hack.String(args[i]), 10, 64)
		if err != nil {
			return err
		}

		params[i] = score
		params[i+1] = args[i+1]
	}

	if n, err := c.app.zset_add(key, params); err != nil {
		return err
	} else {
		c.writeInteger(n)
	}

	return nil
}
Пример #7
0
func (c *client) handleRequest(req [][]byte) {
	var err error

	if len(req) == 0 {
		err = ErrEmptyCommand
	} else {
		c.cmd = strings.ToLower(hack.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()
}
Пример #8
0
func zparseRange(c *client, key []byte, startBuf []byte, stopBuf []byte) (offset int, limit int, err error) {
	var start int
	var stop int
	if start, err = strconv.Atoi(hack.String(startBuf)); err != nil {
		return
	}

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

	if start < 0 || stop < 0 {
		//refer redis implementation
		var size int64
		size, err = c.app.zset_card(key)
		if err != nil {
			return
		}

		llen := int(size)

		if start < 0 {
			start = llen + start
		}
		if stop < 0 {
			stop = llen + stop
		}

		if start < 0 {
			start = 0
		}

		if start >= llen {
			offset = -1
			return
		}
	}

	if start > stop {
		offset = -1
		return
	}

	offset = start
	limit = (stop - start) + 1
	return
}
Пример #9
0
func Int(v []byte, err error) (int64, error) {
	if err != nil {
		return 0, err
	} else if v == nil {
		return 0, nil
	}

	return strconv.ParseInt(hack.String(v), 10, 64)
}
Пример #10
0
func String(v []byte, err error) (string, error) {
	if err != nil {
		return "", err
	} else if v == nil {
		return "", nil
	}

	return hack.String(v), nil
}
Пример #11
0
func Float(v []byte, err error) (float64, error) {
	if err != nil {
		return 0, err
	} else if v == nil {
		return 0, nil
	}

	return strconv.ParseFloat(hack.String(v), 64)
}
Пример #12
0
func decrbyCommand(c *client) error {
	args := c.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	delta, err := strconv.ParseInt(hack.String(args[1]), 10, 64)
	if err != nil {
		return err
	}

	if n, err := c.app.kv_incr(c.args[0], -delta); err != nil {
		return err
	} else {
		c.writeInteger(n)
	}

	return nil
}
Пример #13
0
func hincrbyCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	delta, err := strconv.ParseInt(hack.String(args[2]), 10, 64)
	if err != nil {
		return err
	}

	var n int64
	if n, err = c.app.hash_incrby(args[0], args[1], delta); err != nil {
		return err
	} else {
		c.writeInteger(n)
	}
	return nil
}
Пример #14
0
func lindexCommand(c *client) error {
	args := c.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	index, err := strconv.ParseInt(hack.String(args[1]), 10, 64)
	if err != nil {
		return err
	}

	if v, err := c.app.list_index(args[0], int32(index)); err != nil {
		return err
	} else {
		c.writeBulk(v)
	}

	return nil
}
Пример #15
0
func zincrbyCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	key := args[0]

	delta, err := strconv.ParseInt(hack.String(args[1]), 10, 64)
	if err != nil {
		return err
	}

	if v, err := c.app.zset_incrby(key, delta, args[2]); err != nil {
		return err
	} else {
		c.writeBulk(v)
	}

	return nil
}
Пример #16
0
func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err error) {
	if strings.ToLower(hack.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 = strconv.ParseInt(hack.String(minBuf), 10, 64)
		if err != nil {
			return
		}

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

		if lopen {
			min++
		}
	}

	if strings.ToLower(hack.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 = strconv.ParseInt(hack.String(maxBuf), 10, 64)
		if err != nil {
			return
		}

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

		if ropen {
			max--
		}
	}

	return
}