diff --git a/structure/string.go b/structure/string.go index 318ef171..bced6b2a 100644 --- a/structure/string.go +++ b/structure/string.go @@ -241,6 +241,34 @@ func (s *StringStructure) IncrByFloat(key []byte, amount float64, ttl time.Durat return s.Set(key, newValue, ttl) } +// Decr decrements the integer value of a key by 1 +// If the key does not exist, it will be created +// If the key exists, it will be overwritten +// If the key is expired, it will be deleted +// If the key is not expired, it will be updated +func (s *StringStructure) Decr(key []byte, ttl time.Duration) error { + // Get the old value + oldValue, err := s.Get(key) + if err != nil { + return err + } + + // Convert the old value to an integer + oldIntValue, err := strconv.Atoi(string(oldValue)) + if err != nil { + return err + } + + // Decrement the integer value + newIntValue := oldIntValue - 1 + + // Convert the new integer value to a byte slice + newValue := []byte(strconv.Itoa(newIntValue)) + + // Set the value + return s.Set(key, newValue, ttl) +} + // encodeStringValue encodes the value // format: [type][expire][value] // type: 1 byte diff --git a/structure/string_test.go b/structure/string_test.go index 6307d9c0..706f9f3c 100644 --- a/structure/string_test.go +++ b/structure/string_test.go @@ -156,3 +156,20 @@ func TestStringStructure_IncrByFloat(t *testing.T) { v2, _ := str.Get(randkv.GetTestKey(1)) assert.Equal(t, string(v2), "3.2") } + +func TestStringStructure_Decr(t *testing.T) { + str := initdb() + + err = str.Set(randkv.GetTestKey(1), []byte("1"), 0) + assert.Nil(t, err) + + err := str.Decr(randkv.GetTestKey(1), 0) + assert.Nil(t, err) + v1, _ := str.Get(randkv.GetTestKey(1)) + assert.Equal(t, string(v1), "0") + + err = str.Decr(randkv.GetTestKey(1), 0) + assert.Nil(t, err) + v2, _ := str.Get(randkv.GetTestKey(1)) + assert.Equal(t, string(v2), "-1") +}