From 95b0ddded3ec76b58c3281db2fce4945d073ec00 Mon Sep 17 00:00:00 2001 From: Saeid Aghapour Date: Sun, 9 Jul 2023 16:32:15 +0330 Subject: [PATCH] implement Hash method HMGet (#136) --- structure/hash.go | 59 ++++++++++++++++++++++++++++++++++++++++++ structure/hash_test.go | 27 +++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/structure/hash.go b/structure/hash.go index 47c8cc1d..8cb7b8cf 100644 --- a/structure/hash.go +++ b/structure/hash.go @@ -220,6 +220,65 @@ func (hs *HashStructure) HGet(k string, f interface{}) (interface{}, error) { return valueToInterface, nil } +// HMGet gets the string value of a hash field. +func (hs *HashStructure) HMGet(k string, f ...interface{}) ([]interface{}, error) { + // Convert the parameters to bytes + key := stringToBytesWithKey(k) + var interfaces []interface{} + + for _, fi := range f { + // Convert the parameters to bytes + field, err, _ := interfaceToBytes(fi) + if err != nil { + return nil, err + } + + // Check the parameters + if len(key) == 0 || len(field) == 0 { + return nil, _const.ErrKeyIsEmpty + } + + // Find the hash metadata by the given key + hashMeta, err := hs.findHashMeta(k, Hash) + if err != nil { + return nil, err + } + + // If the counter is 0, return nil + if hashMeta.counter == 0 { + return nil, nil + } + + // Create a new HashField + hf := &HashField{ + field: field, + key: key, + version: hashMeta.version, + } + + // Encode the HashField + hfBuf := hf.encodeHashField() + + // Get the field from the database + value, err := hs.db.Get(hfBuf) + if err != nil { + return nil, err + } + + // Get the value type from the hashValueTypes + valueType := hs.hashValueType + + // Values of different types need to be converted to corresponding types + valueToInterface, err := byteToInterface(value, valueType) + if err != nil { + return nil, err + } + interfaces = append(interfaces, valueToInterface) + } + + return interfaces, nil +} + // HDel deletes one field from a hash. func (hs *HashStructure) HDel(k string, f interface{}) (bool, error) { // Convert the parameters to bytes diff --git a/structure/hash_test.go b/structure/hash_test.go index f36a4a05..a08f9cff 100644 --- a/structure/hash_test.go +++ b/structure/hash_test.go @@ -47,6 +47,33 @@ func TestHashStructure_HGet(t *testing.T) { } +func TestHashStructure_HMGet(t *testing.T) { + hash := initHashDB() + defer hash.db.Close() + + ok1, err := hash.HSet("1", []byte("field1"), randkv.RandomValue(10)) + assert.Nil(t, err) + assert.True(t, ok1) + + v1 := randkv.RandomValue(10) + ok2, err := hash.HSet("1", []byte("field1"), v1) + assert.Nil(t, err) + assert.False(t, ok2) + + v2 := randkv.RandomValue(10) + ok3, err := hash.HSet("1", []byte("field2"), v2) + assert.Nil(t, err) + assert.True(t, ok3) + + mulVal, err := hash.HMGet("1", []byte("field1"), []byte("field2")) + assert.Equal(t, v1, mulVal[0]) + assert.Equal(t, v2, mulVal[1]) + + _, err = hash.HGet("1", []byte("field3")) + assert.Equal(t, err, _const.ErrKeyNotFound) + +} + func TestHashStructure_HDel(t *testing.T) { hash := initHashDB() defer hash.db.Close()