コード例 #1
0
ファイル: strings.go プロジェクト: rod6/rodis
func getrange(v resp.CommandArgs, ex *CommandExtras) error {
	start, err := strconv.Atoi(string(v[1]))
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}

	end, err := strconv.Atoi(string(v[2]))
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}

	ex.DB.RLock()
	defer ex.DB.RUnlock()

	exists, tipe, _ := ex.DB.Has(v[0])
	if !exists {
		return resp.EmptyBulkString.WriteTo(ex.Buffer)
	}
	if tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	val := ex.DB.GetString(v[0])
	start, end = calcRange(start, end, len(val))
	if end <= start {
		return resp.EmptyBulkString.WriteTo(ex.Buffer)
	}

	return resp.BulkString(val[start:end]).WriteTo(ex.Buffer)
}
コード例 #2
0
ファイル: strings.go プロジェクト: zhangshun2014/rodis
func incrbyfloat(v resp.CommandArgs, ex *CommandExtras) error {
	by, err := strconv.ParseFloat(v[1].String(), 64)
	if err != nil {
		return resp.NewError(ErrNotValidFloat).WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	s, err := ex.DB.Get(v[0])
	if err != nil && err != leveldb.ErrNotFound {
		return err
	}
	val := 0.0
	if err != nil && err == leveldb.ErrNotFound {
		val += by
	} else {
		val, err = strconv.ParseFloat(string(s), 64)
		if err != nil {
			return resp.NewError(ErrNotValidFloat).WriteTo(ex.Buffer)
		}
		val += by
	}

	s = []byte(strconv.FormatFloat(val, 'f', -1, 64))
	if err = ex.DB.Put(v[0], s); err != nil {
		return err
	}
	return resp.BulkString(s).WriteTo(ex.Buffer)
}
コード例 #3
0
ファイル: strings.go プロジェクト: rod6/rodis
func getbit(v resp.CommandArgs, ex *CommandExtras) error {
	ex.DB.RLock()
	defer ex.DB.RUnlock()

	exists, tipe, _ := ex.DB.Has(v[0])
	if !exists {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}
	if tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	val := ex.DB.GetString(v[0])

	offset, err := strconv.Atoi(string(v[1]))
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}

	if offset >= 8*len(val) {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}

	byten := offset / 8
	pos := offset % 8

	k := val[byten] >> uint32(7-pos) & 0x01
	return resp.Integer(k).WriteTo(ex.Buffer)
}
コード例 #4
0
ファイル: strings.go プロジェクト: rod6/rodis
func setrange(v resp.CommandArgs, ex *CommandExtras) error {
	i64, err := strconv.ParseInt(string(v[1]), 10, 32)
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}
	offset := int(i64)
	if offset < 0 {
		return resp.NewError(ErrOffsetOutRange).WriteTo(ex.Buffer)
	}
	if offset+len(v[2]) > 536870912 { // 512M is the limit length
		return resp.NewError(ErrStringExccedLimit).WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	exists, tipe, expireAt := ex.DB.Has(v[0])
	if exists && tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	val := []byte("")
	if exists {
		val = ex.DB.GetString(v[0])
	}

	if len(val) < offset+len(v[2]) {
		val = append(val, make([]byte, len(v[2])+offset-len(val))...)
	}
	copy(val[offset:], v[2])

	ex.DB.PutString(v[0], val, expireAt)
	return resp.Integer(len(val)).WriteTo(ex.Buffer)
}
コード例 #5
0
ファイル: strings.go プロジェクト: zhangshun2014/rodis
func getrange(v resp.CommandArgs, ex *CommandExtras) error {
	start, err := strconv.Atoi(string(v[1]))
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}

	end, err := strconv.Atoi(string(v[2]))
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}

	ex.DB.RLock()
	defer ex.DB.RUnlock()

	val, err := ex.DB.Get(v[0])
	if err != nil && err != leveldb.ErrNotFound {
		return err
	}
	if err == leveldb.ErrNotFound {
		return resp.EmptyBulkString.WriteTo(ex.Buffer)
	}

	start, end = calcRange(start, end, len(val))
	if end <= start {
		return resp.EmptyBulkString.WriteTo(ex.Buffer)
	}

	return resp.BulkString(val[start:end]).WriteTo(ex.Buffer)
}
コード例 #6
0
ファイル: strings.go プロジェクト: zhangshun2014/rodis
func setrange(v resp.CommandArgs, ex *CommandExtras) error {
	i64, err := strconv.ParseInt(string(v[1]), 10, 32)
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}
	offset := int(i64)
	if offset < 0 {
		return resp.NewError(ErrOffsetOutRange).WriteTo(ex.Buffer)
	}
	if offset+len(v[2]) > 536870912 { // 512M is the limit length
		return resp.NewError(ErrStringExccedLimit).WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	val, err := ex.DB.Get(v[0])
	if err != nil && err != leveldb.ErrNotFound {
		return err
	}
	if len(val) < offset+len(v[2]) {
		val = append(val, make([]byte, len(v[2])+offset-len(val))...)
	}
	copy(val[offset:], v[2])

	if err = ex.DB.Put(v[0], val); err != nil {
		return err
	}
	return resp.Integer(len(val)).WriteTo(ex.Buffer)
}
コード例 #7
0
ファイル: strings.go プロジェクト: rod6/rodis
func incrbyfloat(v resp.CommandArgs, ex *CommandExtras) error {
	by, err := strconv.ParseFloat(v[1].String(), 64)
	if err != nil {
		return resp.NewError(ErrNotValidFloat).WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	exists, tipe, expireAt := ex.DB.Has(v[0])
	if exists && tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	newVal := 0.0
	if !exists {
		newVal += by
	} else {
		val := ex.DB.GetString(v[0])
		f, err := strconv.ParseFloat(string(val), 64)
		if err != nil {
			return resp.NewError(ErrNotValidFloat).WriteTo(ex.Buffer)
		}
		newVal = f + by
	}

	s := []byte(strconv.FormatFloat(newVal, 'f', -1, 64))
	ex.DB.PutString(v[0], s, expireAt)
	return resp.BulkString(s).WriteTo(ex.Buffer)
}
コード例 #8
0
ファイル: command.go プロジェクト: zhangshun2014/rodis
// Handle command
func Handle(v resp.Array, ex *CommandExtras) error {
	ex.Buffer.Truncate(0) // Truncate all data in the buffer

	if len(v) == 0 {
		log6.Debug("Command handler, len of the input array is 0")
		return resp.NewError(ErrFmtNoCommand).WriteTo(ex.Buffer)
	}

	args := v.ToArgs()
	//log6.Debug("Command handling:%v", humanArgs(args))

	cmd := strings.ToLower(args[0].String())
	a, err := findCmdFunc(cmd)
	if err != nil {
		log6.Debug("Command handler, cannt found command: %v", cmd)
		return resp.NewError(ErrFmtUnknownCommand, cmd).WriteTo(ex.Buffer)
	}

	if a.c != 0 && len(v) != a.c { //a.c = 0 means to check the number in f
		return resp.NewError(ErrFmtWrongNumberArgument, cmd).WriteTo(ex.Buffer)
	}

	if !ex.IsConnAuthed && ex.Password != "" && cmd != "auth" {
		return resp.NewError(ErrAuthed).WriteTo(ex.Buffer)
	}

	return a.f(args[1:], ex)
}
コード例 #9
0
ファイル: hashes.go プロジェクト: rod6/rodis
func hdel(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) < 2 {
		return resp.NewError(ErrFmtWrongNumberArgument, "hdel").WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	keyExists, tipe, _ := ex.DB.Has(v[0])
	if !keyExists {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}
	if keyExists && tipe != storage.Hash {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	fields := [][]byte{}
	for _, field := range v[1:] {
		fields = append(fields, []byte(field))
	}
	hash := ex.DB.GetHashFields(v[0], fields)

	count := 0
	for _, value := range hash {
		if value != nil {
			count++
		}
	}
	ex.DB.DeleteHashFields(v[0], fields)
	return resp.Integer(count).WriteTo(ex.Buffer)
}
コード例 #10
0
ファイル: hashes.go プロジェクト: rod6/rodis
func hincrbyfloat(v resp.CommandArgs, ex *CommandExtras) error {
	by, err := strconv.ParseFloat(v[2].String(), 64)
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	keyExists, tipe, expireAt := ex.DB.Has(v[0])
	if keyExists && tipe != storage.Hash {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	hash := ex.DB.GetHashFields(v[0], [][]byte{v[1]})

	newVal := 0.0
	if hash[string(v[1])] == nil {
		newVal += by
	} else {
		f, err := strconv.ParseFloat(string(hash[string(v[1])]), 64)
		if err != nil {
			return resp.NewError(ErrNotValidFloat).WriteTo(ex.Buffer)
		}
		newVal = f + by
	}
	hash[string(v[1])] = []byte(strconv.FormatFloat(newVal, 'f', -1, 64))

	ex.DB.PutHash(v[0], hash, expireAt)
	return resp.BulkString(hash[string(v[1])]).WriteTo(ex.Buffer)
}
コード例 #11
0
ファイル: hashes.go プロジェクト: wshn13/rodis
func hmget(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) < 2 {
		return resp.NewError(ErrFmtWrongNumberArgument, "hmget").WriteTo(ex.Buffer)
	}

	ex.DB.RLock()
	defer ex.DB.RUnlock()

	keyExists, tipe, _ := ex.DB.Has(v[0])
	if keyExists && tipe != storage.Hash {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	fields := [][]byte{}
	for _, field := range v[1:] {
		fields = append(fields, []byte(field))
	}
	hash := ex.DB.GetHashFields(v[0], fields)

	arr := resp.Array{}
	for _, value := range hash {
		arr = append(arr, resp.BulkString(value))
	}
	return arr.WriteTo(ex.Buffer)
}
コード例 #12
0
ファイル: connection.go プロジェクト: rod6/rodis
func auth(v resp.CommandArgs, ex *CommandExtras) error {
	if ex.Password == "" {
		return resp.NewError(ErrNoNeedPassword).WriteTo(ex.Buffer)
	}
	if v[0].String() != ex.Password {
		ex.IsConnAuthed = false
		return resp.NewError(ErrWrongPassword).WriteTo(ex.Buffer)
	}
	ex.IsConnAuthed = true
	return resp.OkSimpleString.WriteTo(ex.Buffer)
}
コード例 #13
0
ファイル: connection.go プロジェクト: rod6/rodis
func selectDB(v resp.CommandArgs, ex *CommandExtras) error {
	s := v[0].String()
	index, err := strconv.Atoi(s)
	if err != nil {
		return resp.NewError(ErrSelectInvalidIndex).WriteTo(ex.Buffer)
	}

	if index < 0 || index > 15 {
		return resp.NewError(ErrSelectInvalidIndex).WriteTo(ex.Buffer)
	}
	ex.DB = storage.SelectStorage(index)
	return resp.OkSimpleString.WriteTo(ex.Buffer)
}
コード例 #14
0
ファイル: strings.go プロジェクト: rod6/rodis
func bitcount(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) == 0 {
		return resp.NewError(ErrFmtWrongNumberArgument, "bitcount").WriteTo(ex.Buffer)
	}

	ex.DB.RLock()
	defer ex.DB.RUnlock()

	exists, tipe, _ := ex.DB.Has(v[0])
	if !exists {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}
	if tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	if len(v) != 1 && len(v) != 3 {
		return resp.NewError(ErrFmtSyntax).WriteTo(ex.Buffer)
	}

	val := ex.DB.GetString(v[0])

	start := 0
	end := len(val)
	var err error

	if len(v) == 3 {
		start, err = strconv.Atoi(string(v[1]))
		if err != nil {
			return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
		}

		end, err = strconv.Atoi(string(v[2]))
		if err != nil {
			return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
		}

		start, end = calcRange(start, end, len(val))
	}

	if end <= start {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}

	sum := 0
	for _, b := range val[start:end] {
		sum += countSetBits[b]
	}
	return resp.Integer(sum).WriteTo(ex.Buffer)
}
コード例 #15
0
ファイル: strings.go プロジェクト: rod6/rodis
func setbit(v resp.CommandArgs, ex *CommandExtras) error {
	i64, err := strconv.ParseInt(string(v[1]), 10, 32)
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}
	offset := uint32(i64)
	pos := offset % 8
	byten := offset / 8

	if int(byten)+1 > STRLIMIT {
		return resp.NewError(ErrStringExccedLimit).WriteTo(ex.Buffer)
	}

	bit, err := strconv.Atoi(string(v[2]))
	if err != nil || bit != 0 && bit != 1 {
		return resp.NewError(ErrBitValueInvalid).WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	exists, tipe, expireAt := ex.DB.Has(v[0])
	if exists && tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	val := []byte("")
	if exists {
		val = ex.DB.GetString(v[0])
	}

	if uint32(len(val)) < byten+1 {
		val = append(val, make([]byte, int(byten)+1-len(val))...)
	}

	k := val[byten] >> uint32(7-pos) & 0x01

	switch bit {
	case 0:
		clear := byte(^(0x01 << (7 - pos)))
		val[byten] = val[byten] & clear
	case 1:
		set := byte(0x01 << (7 - pos))
		val[byten] = val[byten] | set
	}

	ex.DB.PutString(v[0], val, expireAt)
	return resp.Integer(k).WriteTo(ex.Buffer)
}
コード例 #16
0
ファイル: strings.go プロジェクト: zhangshun2014/rodis
func bitcount(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) == 0 {
		return resp.NewError(ErrFmtWrongNumberArgument, "bitcount").WriteTo(ex.Buffer)
	}

	ex.DB.RLock()
	defer ex.DB.RUnlock()

	val, err := ex.DB.Get(v[0])
	if err != nil && err != leveldb.ErrNotFound {
		return err
	}

	if err == leveldb.ErrNotFound {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}

	if len(v) != 1 && len(v) != 3 {
		return resp.NewError(ErrFmtSyntax).WriteTo(ex.Buffer)
	}

	start := 0
	end := len(val)

	if len(v) == 3 {
		start, err = strconv.Atoi(string(v[1]))
		if err != nil {
			return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
		}

		end, err = strconv.Atoi(string(v[2]))
		if err != nil {
			return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
		}

		start, end = calcRange(start, end, len(val))
	}

	if end <= start {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}

	sum := 0
	for _, b := range val[start:end] {
		sum += countSetBits[b]
	}
	return resp.Integer(sum).WriteTo(ex.Buffer)
}
コード例 #17
0
ファイル: strings.go プロジェクト: rod6/rodis
func incrby(v resp.CommandArgs, ex *CommandExtras) error {
	by, err := strconv.ParseInt(v[1].String(), 10, 64)
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}
	return incrdecrHelper(v, ex, by)
}
コード例 #18
0
ファイル: keys.go プロジェクト: rod6/rodis
func del(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) == 0 {
		return resp.NewError(ErrFmtWrongNumberArgument, "del").WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	count := 0
	for _, key := range v {
		exists, tipe, _ := ex.DB.Has(key)
		if !exists {
			continue
		}
		switch tipe {
		case storage.String:
			ex.DB.DeleteString(key)
		case storage.Hash:
			ex.DB.DeleteHash(key)
		}

		count++
	}
	return resp.Integer(count).WriteTo(ex.Buffer)
}
コード例 #19
0
ファイル: strings.go プロジェクト: zhangshun2014/rodis
func msetnx(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) == 0 || len(v)%2 != 0 {
		return resp.NewError(ErrFmtWrongNumberArgument, "msetnx").WriteTo(ex.Buffer)
	}

	batch := new(leveldb.Batch)
	for i := 0; i < len(v); {
		batch.Put(v[i], v[i+1])
		i += 2
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	for i := 0; i < len(v); {
		_, err := ex.DB.Get(v[i])
		if err != nil && err != leveldb.ErrNotFound {
			return err
		}
		if err != leveldb.ErrNotFound {
			return resp.ZeroInteger.WriteTo(ex.Buffer)
		}
		i += 2
	}

	if err := ex.DB.WriteBatch(batch); err != nil {
		return err
	}
	return resp.OneInteger.WriteTo(ex.Buffer)
}
コード例 #20
0
ファイル: strings.go プロジェクト: zhangshun2014/rodis
func mget(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) < 1 {
		return resp.NewError(ErrFmtWrongNumberArgument, "mget").WriteTo(ex.Buffer)
	}

	ex.DB.RLock()
	defer ex.DB.RUnlock()

	arr := make(resp.Array, len(v))

	for i, g := range v {
		val, err := ex.DB.Get(g)

		if err != nil && err != leveldb.ErrNotFound {
			return err
		}
		if err == leveldb.ErrNotFound {
			arr[i] = resp.NilBulkString
		} else {
			arr[i] = resp.BulkString(val)
		}
	}

	return arr.WriteTo(ex.Buffer)
}
コード例 #21
0
ファイル: strings.go プロジェクト: zhangshun2014/rodis
func getbit(v resp.CommandArgs, ex *CommandExtras) error {
	ex.DB.RLock()
	defer ex.DB.RUnlock()

	val, err := ex.DB.Get(v[0])
	if err != nil && err != leveldb.ErrNotFound {
		return err
	}
	if err == leveldb.ErrNotFound {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}

	offset, err := strconv.Atoi(string(v[1]))
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}

	if offset >= 8*len(val) {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}

	byten := offset / 8
	pos := offset % 8

	k := val[byten] >> uint32(7-pos) & 0x01
	return resp.Integer(k).WriteTo(ex.Buffer)
}
コード例 #22
0
ファイル: strings.go プロジェクト: zhangshun2014/rodis
func setbit(v resp.CommandArgs, ex *CommandExtras) error {
	i64, err := strconv.ParseInt(string(v[1]), 10, 32)
	if err != nil {
		return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
	}
	offset := uint32(i64)
	pos := offset % 8
	byten := offset / 8

	bit, err := strconv.Atoi(string(v[2]))
	if err != nil || bit != 0 && bit != 1 {
		return resp.NewError(ErrBitValueInvalid).WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	val, err := ex.DB.Get(v[0])
	if err != nil && err != leveldb.ErrNotFound {
		return err
	}

	if uint32(len(val)) < byten+1 {
		val = append(val, make([]byte, int(byten)+1-len(val))...)
	}

	k := val[byten] >> uint32(7-pos) & 0x01

	switch bit {
	case 0:
		clear := byte(^(0x01 << (7 - pos)))
		val[byten] = val[byten] & clear
	case 1:
		set := byte(0x01 << (7 - pos))
		val[byten] = val[byten] | set
	}
	if err := ex.DB.Put(v[0], val); err != nil {
		return err
	}
	return resp.Integer(k).WriteTo(ex.Buffer)
}
コード例 #23
0
ファイル: hashes.go プロジェクト: rod6/rodis
func hmset(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) <= 1 || len(v)%2 != 1 {
		return resp.NewError(ErrFmtWrongNumberArgument, "hmset").WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	keyExists, tipe, expireAt := ex.DB.Has(v[0])
	if keyExists && tipe != storage.Hash {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	hash := make(map[string][]byte)
	for i := 1; i < len(v); {
		hash[string(v[i])] = v[i+1]
		i += 2
	}
	ex.DB.PutHash(v[0], hash, expireAt)
	return resp.OkSimpleString.WriteTo(ex.Buffer)
}
コード例 #24
0
ファイル: strings.go プロジェクト: rod6/rodis
// use appendx for append command, because append is a key word of golang
func appendx(v resp.CommandArgs, ex *CommandExtras) error {
	ex.DB.Lock()
	defer ex.DB.Unlock()

	exists, tipe, expireAt := ex.DB.Has(v[0])
	if exists && tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	val := []byte("")
	if exists {
		val = ex.DB.GetString(v[0])
	}
	if len(val)+len(v[1]) > STRLIMIT {
		return resp.NewError(ErrStringExccedLimit).WriteTo(ex.Buffer)
	}

	val = append(val, v[1]...)
	ex.DB.PutString(v[0], val, expireAt)
	return resp.Integer(len(val)).WriteTo(ex.Buffer)
}
コード例 #25
0
ファイル: strings.go プロジェクト: rod6/rodis
func get(v resp.CommandArgs, ex *CommandExtras) error {
	ex.DB.RLock()
	defer ex.DB.RUnlock()

	exists, tipe, _ := ex.DB.Has(v[0])
	if !exists {
		return resp.NilBulkString.WriteTo(ex.Buffer)
	}
	if tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}
	val := ex.DB.GetString(v[0])
	return resp.BulkString(val).WriteTo(ex.Buffer)
}
コード例 #26
0
ファイル: strings.go プロジェクト: rod6/rodis
func incrdecrHelper(v resp.CommandArgs, ex *CommandExtras, by int64) error {
	ex.DB.Lock()
	defer ex.DB.Unlock()

	exists, tipe, expireAt := ex.DB.Has(v[0])
	if exists && tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	newVal := int64(0)
	if !exists {
		newVal += by
	} else {
		val := ex.DB.GetString(v[0])
		i, err := strconv.ParseInt(string(val), 10, 64)
		if err != nil {
			return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer)
		}
		newVal = i + by
	}

	ex.DB.PutString(v[0], []byte(strconv.FormatInt(newVal, 10)), expireAt)
	return resp.Integer(newVal).WriteTo(ex.Buffer)
}
コード例 #27
0
ファイル: hashes.go プロジェクト: rod6/rodis
func hget(v resp.CommandArgs, ex *CommandExtras) error {
	ex.DB.RLock()
	defer ex.DB.RUnlock()

	keyExists, tipe, _ := ex.DB.Has(v[0])
	if !keyExists {
		return resp.NilBulkString.WriteTo(ex.Buffer)
	}
	if keyExists && tipe != storage.Hash {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	hash := ex.DB.GetHashFields(v[0], [][]byte{v[1]})
	return resp.BulkString(hash[string(v[1])]).WriteTo(ex.Buffer)
}
コード例 #28
0
ファイル: strings.go プロジェクト: rod6/rodis
func mset(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v) == 0 || len(v)%2 != 0 {
		return resp.NewError(ErrFmtWrongNumberArgument, "mset").WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	for i := 0; i < len(v); {
		ex.DB.PutString(v[i], v[i+1], nil)
		i += 2
	}

	return resp.OkSimpleString.WriteTo(ex.Buffer)
}
コード例 #29
0
ファイル: strings.go プロジェクト: rod6/rodis
func getset(v resp.CommandArgs, ex *CommandExtras) error {
	if len(v[1]) > STRLIMIT {
		return resp.NewError(ErrStringExccedLimit).WriteTo(ex.Buffer)
	}

	ex.DB.Lock()
	defer ex.DB.Unlock()

	exists, tipe, expireAt := ex.DB.Has(v[0])
	if exists && tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}
	var oldValue []byte
	if exists {
		oldValue = ex.DB.GetString(v[0])
	}

	ex.DB.PutString(v[0], v[1], expireAt)

	if !exists {
		return resp.NilBulkString.WriteTo(ex.Buffer)
	}
	return resp.BulkString(oldValue).WriteTo(ex.Buffer)
}
コード例 #30
0
ファイル: strings.go プロジェクト: rod6/rodis
func strlen(v resp.CommandArgs, ex *CommandExtras) error {
	ex.DB.RLock()
	defer ex.DB.RUnlock()

	exists, tipe, _ := ex.DB.Has(v[0])
	if !exists {
		return resp.ZeroInteger.WriteTo(ex.Buffer)
	}
	if tipe != storage.String {
		return resp.NewError(ErrWrongType).WriteTo(ex.Buffer)
	}

	val := ex.DB.GetString(v[0])
	return resp.Integer(len(val)).WriteTo(ex.Buffer)
}