diff --git a/structure/string.go b/structure/string.go index 99f79d37..7125820a 100644 --- a/structure/string.go +++ b/structure/string.go @@ -32,12 +32,49 @@ func NewStringStructure(options config.Options) (*StringStructure, error) { return &StringStructure{db: db}, nil } +// encodeStringValue encodes a string value +func StringToBytesWithKeyAndValue(key, value string) ([]byte, []byte) { + return []byte(key), []byte(value) +} + +// stringToBytesWithKey converts a string to a byte slice +func stringToBytesWithKey(key string) []byte { + return []byte(key) +} + +// interfaceToBytes converts an interface to a byte slice +func interfaceToBytes(value interface{}) ([]byte, error) { + switch value := value.(type) { + case string: + return []byte(value), nil + case int: + return []byte(strconv.Itoa(value)), nil + case int64: + return []byte(strconv.FormatInt(value, 10)), nil + case float64: + return []byte(strconv.FormatFloat(value, 'f', -1, 64)), nil + case bool: + return []byte(strconv.FormatBool(value)), nil + case []byte: + return value, nil + default: + return nil, errors.New("unsupported type") + } +} + // Set sets the value of a key // 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) Set(key, value []byte, ttl time.Duration) error { +// func (s *StringStructure) Set(key, value []byte, ttl time.Duration) error { +func (s *StringStructure) Set(k string, v interface{}, ttl time.Duration) error { + key := stringToBytesWithKey(k) + value, err := interfaceToBytes(v) + if err != nil { + return err + } + if value == nil { return nil } @@ -57,7 +94,9 @@ func (s *StringStructure) Set(key, value []byte, ttl time.Duration) error { // If the key exists, it will return the value // If the key is expired, it will be deleted and return nil // If the key is not expired, it will be updated and return the value -func (s *StringStructure) Get(key []byte) ([]byte, error) { +func (s *StringStructure) Get(k string) ([]byte, error) { + key := stringToBytesWithKey(k) + // Get the value value, err := s.db.Get(key) if err != nil { @@ -73,7 +112,8 @@ func (s *StringStructure) Get(key []byte) ([]byte, error) { // If the key exists, it will be deleted // If the key is expired, it will be deleted and return nil // If the key is not expired, it will be updated and return nil -func (s *StringStructure) Del(key []byte) error { +func (s *StringStructure) Del(k string) error { + key := stringToBytesWithKey(k) // Delete the value return s.db.Delete(key) } @@ -83,7 +123,8 @@ func (s *StringStructure) Del(key []byte) error { // If the key exists, it will return "string" // If the key is expired, it will be deleted and return "" // If the key is not expired, it will be updated and return "string" -func (s *StringStructure) Type(key []byte) (string, error) { +func (s *StringStructure) Type(k string) (string, error) { + key := stringToBytesWithKey(k) // Get the value value, err := s.db.Get(key) if err != nil { @@ -105,7 +146,8 @@ func (s *StringStructure) Type(key []byte) (string, error) { // If the key exists, it will return the length of the value // If the key is expired, it will be deleted and return 0 // If the key is not expired, it will be updated and return the length of the value -func (s *StringStructure) StrLen(key []byte) (int, error) { +func (s *StringStructure) StrLen(k string) (int, error) { + key := stringToBytesWithKey(k) // Get the value value, err := s.db.Get(key) if err != nil { @@ -123,7 +165,7 @@ func (s *StringStructure) StrLen(key []byte) (int, error) { } // GetSet sets the value of a key and returns its old value -func (s *StringStructure) GetSet(key, value []byte, ttl time.Duration) ([]byte, error) { +func (s *StringStructure) GetSet(key string, value interface{}, ttl time.Duration) ([]byte, error) { // Get the old value oldValue, err := s.Get(key) if err != nil { @@ -141,22 +183,27 @@ func (s *StringStructure) GetSet(key, value []byte, ttl time.Duration) ([]byte, } // Append appends a value to the value of a key -func (s *StringStructure) Append(key, value []byte, ttl time.Duration) error { +func (s *StringStructure) Append(key string, v interface{}, ttl time.Duration) error { // Get the old value oldValue, err := s.Get(key) if err != nil { return err } + value, err := interfaceToBytes(v) + if err != nil { + return err + } + // Append the value newValue := append(oldValue, value...) // Set the value - return s.Set(key, newValue, ttl) + return s.Set(key, string(newValue), ttl) } // Incr increments the integer value of a key by 1 -func (s *StringStructure) Incr(key []byte, ttl time.Duration) error { +func (s *StringStructure) Incr(key string, ttl time.Duration) error { // Get the old value oldValue, err := s.Get(key) if err != nil { @@ -176,11 +223,11 @@ func (s *StringStructure) Incr(key []byte, ttl time.Duration) error { newValue := []byte(strconv.Itoa(newIntValue)) // Set the value - return s.Set(key, newValue, ttl) + return s.Set(key, string(newValue), ttl) } // IncrBy increments the integer value of a key by the given amount -func (s *StringStructure) IncrBy(key []byte, amount int, ttl time.Duration) error { +func (s *StringStructure) IncrBy(key string, amount int, ttl time.Duration) error { // Get the old value oldValue, err := s.Get(key) if err != nil { @@ -200,11 +247,11 @@ func (s *StringStructure) IncrBy(key []byte, amount int, ttl time.Duration) erro newValue := []byte(strconv.Itoa(newIntValue)) // Set the value - return s.Set(key, newValue, ttl) + return s.Set(key, string(newValue), ttl) } // IncrByFloat increments the float value of a key by the given amount -func (s *StringStructure) IncrByFloat(key []byte, amount float64, ttl time.Duration) error { +func (s *StringStructure) IncrByFloat(key string, amount float64, ttl time.Duration) error { // Get the old value oldValue, err := s.Get(key) if err != nil { @@ -224,11 +271,11 @@ func (s *StringStructure) IncrByFloat(key []byte, amount float64, ttl time.Durat newValue := []byte(strconv.FormatFloat(newFloatValue, 'f', -1, 64)) // Set the value - return s.Set(key, newValue, ttl) + return s.Set(key, string(newValue), ttl) } // Decr decrements the integer value of a key by 1 -func (s *StringStructure) Decr(key []byte, ttl time.Duration) error { +func (s *StringStructure) Decr(key string, ttl time.Duration) error { // Get the old value oldValue, err := s.Get(key) if err != nil { @@ -248,11 +295,11 @@ func (s *StringStructure) Decr(key []byte, ttl time.Duration) error { newValue := []byte(strconv.Itoa(newIntValue)) // Set the value - return s.Set(key, newValue, ttl) + return s.Set(key, string(newValue), ttl) } // DecrBy decrements the integer value of a key by the given amount -func (s *StringStructure) DecrBy(key []byte, amount int, ttl time.Duration) error { +func (s *StringStructure) DecrBy(key string, amount int, ttl time.Duration) error { // Get the old value oldValue, err := s.Get(key) if err != nil { @@ -272,11 +319,11 @@ func (s *StringStructure) DecrBy(key []byte, amount int, ttl time.Duration) erro newValue := []byte(strconv.Itoa(newIntValue)) // Set the value - return s.Set(key, newValue, ttl) + return s.Set(key, string(newValue), ttl) } // Exists checks if a key exists -func (s *StringStructure) Exists(key []byte) (bool, error) { +func (s *StringStructure) Exists(key string) (bool, error) { // Get the value _, err := s.Get(key) if err != nil { @@ -290,7 +337,7 @@ func (s *StringStructure) Exists(key []byte) (bool, error) { } // Expire sets the expiration time of a key -func (s *StringStructure) Expire(key []byte, ttl time.Duration) error { +func (s *StringStructure) Expire(key string, ttl time.Duration) error { // Get the value value, err := s.Get(key) if err != nil { @@ -298,11 +345,11 @@ func (s *StringStructure) Expire(key []byte, ttl time.Duration) error { } // Set the value - return s.Set(key, value, ttl) + return s.Set(key, string(value), ttl) } // Persist removes the expiration time of a key -func (s *StringStructure) Persist(key []byte) error { +func (s *StringStructure) Persist(key string) error { // Get the value value, err := s.Get(key) if err != nil { @@ -310,7 +357,7 @@ func (s *StringStructure) Persist(key []byte) error { } // Set the value - return s.Set(key, value, 0) + return s.Set(key, string(value), 0) } // encodeStringValue encodes the value diff --git a/structure/string_test.go b/structure/string_test.go index 9ab732c7..e370e606 100644 --- a/structure/string_test.go +++ b/structure/string_test.go @@ -23,45 +23,45 @@ func initdb() *StringStructure { func TestStringStructure_Get(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), randkv.RandomValue(100), 0) + err = str.Set("1", randkv.RandomValue(100), 0) assert.Nil(t, err) - err = str.Set(randkv.GetTestKey(2), randkv.RandomValue(100), 2*time.Second) + err = str.Set("1", randkv.RandomValue(100), 2*time.Second) assert.Nil(t, err) - value1, err := str.Get(randkv.GetTestKey(1)) + value1, err := str.Get("1") assert.Nil(t, err) assert.NotNil(t, value1) time.Sleep(3 * time.Second) - value2, err := str.Get(randkv.GetTestKey(2)) + value2, err := str.Get("1") assert.Equal(t, err, ErrKeyExpired) assert.Nil(t, value2) - _, err = str.Get(randkv.GetTestKey(3)) + _, err = str.Get("3") assert.Equal(t, err, _const.ErrKeyNotFound) } func TestStringStructure_Del(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), randkv.RandomValue(100), 0) + err = str.Set("1", randkv.RandomValue(100), 0) assert.Nil(t, err) - err = str.Del(randkv.GetTestKey(1)) + err = str.Del("1") assert.Nil(t, err) - _, err = str.Get(randkv.GetTestKey(1)) + _, err = str.Get("1") assert.Equal(t, err, _const.ErrKeyNotFound) } func TestStringStructure_Type(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), randkv.RandomValue(100), 0) + err = str.Set("1", randkv.RandomValue(100), 0) assert.Nil(t, err) - keyType, err := str.Type(randkv.GetTestKey(1)) + keyType, err := str.Type("1") TypeString := "string" assert.Equal(t, keyType, TypeString) @@ -71,10 +71,10 @@ func TestStringStructure_Type(t *testing.T) { func TestStringStructure_StrLen(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), randkv.RandomValue(100), 0) + err = str.Set("1", randkv.RandomValue(100), 0) assert.Nil(t, err) - strLen, err := str.StrLen(randkv.GetTestKey(1)) + strLen, err := str.StrLen("1") assert.Nil(t, err) assert.Equal(t, strLen, 112) } @@ -82,11 +82,11 @@ func TestStringStructure_StrLen(t *testing.T) { func TestStringStructure_GetSet(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), randkv.RandomValue(100), 0) + err = str.Set("1", randkv.RandomValue(100), 0) assert.Nil(t, err) - value1, _ := str.Get(randkv.GetTestKey(1)) + value1, _ := str.Get("1") - value2, err := str.GetSet(randkv.GetTestKey(1), randkv.RandomValue(100), 2*time.Second) + value2, err := str.GetSet("1", randkv.RandomValue(100), 2*time.Second) assert.Nil(t, err) assert.NotNil(t, value2) assert.Equal(t, value1, value2) @@ -95,113 +95,109 @@ func TestStringStructure_GetSet(t *testing.T) { func TestStringStructure_Append(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), randkv.RandomValue(10), 0) - //assert.Nil(t, err) - s1, _ := str.Get(randkv.GetTestKey(1)) - t.Log(string(s1)) + err = str.Set("1", randkv.RandomValue(10), 0) + assert.Nil(t, err) - err = str.Append(randkv.GetTestKey(1), randkv.RandomValue(5), 0) - //assert.Nil(t, err) - s2, _ := str.Get(randkv.GetTestKey(1)) - t.Log(string(s2)) + err = str.Append("1", randkv.RandomValue(5), 0) + assert.Nil(t, err) } func TestStringStructure_Incr(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), []byte("1"), 0) + err = str.Set("1", []byte("1"), 0) assert.Nil(t, err) - err := str.Incr(randkv.GetTestKey(1), 0) + err := str.Incr("1", 0) assert.Nil(t, err) - v1, _ := str.Get(randkv.GetTestKey(1)) + v1, _ := str.Get("1") assert.Equal(t, string(v1), "2") - err = str.Incr(randkv.GetTestKey(1), 0) + err = str.Incr("1", 0) assert.Nil(t, err) - v2, _ := str.Get(randkv.GetTestKey(1)) + v2, _ := str.Get("1") assert.Equal(t, string(v2), "3") } func TestStringStructure_IncrBy(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), []byte("1"), 0) + err = str.Set("1", []byte("1"), 0) assert.Nil(t, err) - err := str.IncrBy(randkv.GetTestKey(1), 10, 0) + err := str.IncrBy("1", 10, 0) assert.Nil(t, err) - v1, _ := str.Get(randkv.GetTestKey(1)) + v1, _ := str.Get("1") assert.Equal(t, string(v1), "11") - err = str.IncrBy(randkv.GetTestKey(1), 10, 0) + err = str.IncrBy("1", 10, 0) assert.Nil(t, err) - v2, _ := str.Get(randkv.GetTestKey(1)) + v2, _ := str.Get("1") assert.Equal(t, string(v2), "21") } func TestStringStructure_IncrByFloat(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), []byte("1"), 0) + err = str.Set("1", []byte("1"), 0) assert.Nil(t, err) - err := str.IncrByFloat(randkv.GetTestKey(1), 1.1, 0) + err := str.IncrByFloat("1", 1.1, 0) assert.Nil(t, err) - v1, _ := str.Get(randkv.GetTestKey(1)) + v1, _ := str.Get("1") assert.Equal(t, string(v1), "2.1") - err = str.IncrByFloat(randkv.GetTestKey(1), 1.1, 0) + err = str.IncrByFloat("1", 1.1, 0) assert.Nil(t, err) - v2, _ := str.Get(randkv.GetTestKey(1)) + v2, _ := str.Get("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) + err = str.Set("1", []byte("1"), 0) assert.Nil(t, err) - err := str.Decr(randkv.GetTestKey(1), 0) + err := str.Decr("1", 0) assert.Nil(t, err) - v1, _ := str.Get(randkv.GetTestKey(1)) + v1, _ := str.Get("1") assert.Equal(t, string(v1), "0") - err = str.Decr(randkv.GetTestKey(1), 0) + err = str.Decr("1", 0) assert.Nil(t, err) - v2, _ := str.Get(randkv.GetTestKey(1)) + v2, _ := str.Get("1") assert.Equal(t, string(v2), "-1") } func TestStringStructure_DecrBy(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), []byte("1"), 0) + err = str.Set("1", []byte("1"), 0) assert.Nil(t, err) - err := str.DecrBy(randkv.GetTestKey(1), 10, 0) + err := str.DecrBy("1", 10, 0) assert.Nil(t, err) - v1, _ := str.Get(randkv.GetTestKey(1)) + v1, _ := str.Get("1") assert.Equal(t, string(v1), "-9") - err = str.DecrBy(randkv.GetTestKey(1), 10, 0) + err = str.DecrBy("1", 10, 0) assert.Nil(t, err) - v2, _ := str.Get(randkv.GetTestKey(1)) + v2, _ := str.Get("1") assert.Equal(t, string(v2), "-19") } func TestStringStructure_Exists(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), []byte("1"), 0) + err = str.Set("1", []byte("1"), 0) assert.Nil(t, err) - ok1, err := str.Exists(randkv.GetTestKey(1)) + ok1, err := str.Exists("1") assert.Nil(t, err) assert.Equal(t, ok1, true) - ok2, err := str.Exists(randkv.GetTestKey(1)) + ok2, err := str.Exists("1") assert.Nil(t, err) assert.Equal(t, ok2, true) } @@ -209,17 +205,17 @@ func TestStringStructure_Exists(t *testing.T) { func TestStringStructure_Expire(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), []byte("1"), 0) + err = str.Set("1", []byte("1"), 0) assert.Nil(t, err) - err = str.Expire(randkv.GetTestKey(1), 1*time.Second) + err = str.Expire("1", 1*time.Second) assert.Nil(t, err) - v1, err := str.Get(randkv.GetTestKey(1)) + v1, err := str.Get("1") assert.Nil(t, err) assert.Equal(t, string(v1), "1") time.Sleep(2 * time.Second) - v2, err := str.Get(randkv.GetTestKey(1)) + v2, err := str.Get("1") assert.Equal(t, err, ErrKeyExpired) assert.Equal(t, string(v2), "") } @@ -227,18 +223,18 @@ func TestStringStructure_Expire(t *testing.T) { func TestStringStructure_Persist(t *testing.T) { str := initdb() - err = str.Set(randkv.GetTestKey(1), []byte("1"), 0) + err = str.Set("1", []byte("1"), 0) assert.Nil(t, err) - err = str.Expire(randkv.GetTestKey(1), 1*time.Second) + err = str.Expire("1", 1*time.Second) assert.Nil(t, err) - v1, err := str.Get(randkv.GetTestKey(1)) + v1, err := str.Get("1") assert.Nil(t, err) assert.Equal(t, string(v1), "1") - err = str.Persist(randkv.GetTestKey(1)) + err = str.Persist("1") assert.Nil(t, err) - v2, err := str.Get(randkv.GetTestKey(1)) + v2, err := str.Get("1") assert.Nil(t, err) assert.Equal(t, string(v2), "1") }