diff options
| author | alex <[email protected]> | 2026-07-06 19:21:44 +0200 |
|---|---|---|
| committer | alex <[email protected]> | 2026-07-06 19:21:44 +0200 |
| commit | 291a6c9044723fcbcce18a3cd12509d5fdac4702 (patch) | |
| tree | 6c21f5e00a53667010e3eb556fdd882fac4e52ab | |
| parent | 316b443addb7ec55e27f571ef489f2c19afb3a82 (diff) | |
| download | redis-clone-291a6c9044723fcbcce18a3cd12509d5fdac4702.tar.xz redis-clone-291a6c9044723fcbcce18a3cd12509d5fdac4702.zip | |
added hash support
| -rw-r--r-- | handlers.go | 91 | ||||
| -rw-r--r-- | main.go | 3 | ||||
| -rw-r--r-- | redisDB.go | 8 |
3 files changed, 102 insertions, 0 deletions
diff --git a/handlers.go b/handlers.go index 244d332..a6ae6ef 100644 --- a/handlers.go +++ b/handlers.go @@ -396,4 +396,95 @@ func handleExpire(conn net.Conn, args []string){ item.ExpiresAt = &expiry db.data[key] = item conn.Write(serializeRESP(1)) +} + +func handleHset(conn net.Conn, args []string){ + + if len(args) < 4 || (len(args)-2)%2 != 0 { + err := errors.New("wrong number of arguments for 'HSET'") + conn.Write(serializeRESP(err)) + return + } + key := args[1] + db.mu.Lock() + defer db.mu.Unlock() + + item, exists := db.data[key] + + var hash map[string]string + + if exists { + var ok bool + hash, ok = item.Value.(map[string]string) + if !ok { + conn.Write(serializeRESP(errors.New("WRONGTYPE Operation against a key holding the wrong kind of value"))) + return + } + } else { + hash = make(map[string]string) + } + count := 0 + for i := 2; i < len(args); i += 2 { + hash[args[i]] = args[i+1] + count += 1 + } + db.data[key] = Item{Value: hash} + conn.Write(serializeRESP(count)) +} + +func handleHget(conn net.Conn, args []string) { + if len(args) != 3 { + conn.Write(serializeRESP(errors.New("ERR wrong number of arguments for 'HGET'"))) + return + } + + key := args[1] + field := args[2] + + db.mu.Lock() + defer db.mu.Unlock() + + item, exists := db.data[key] + if !exists { + conn.Write(serializeRESP(nil)) + return + } + + hash, ok := item.Value.(map[string]string) + if !ok { + conn.Write(serializeRESP(errors.New("WRONGTYPE Operation against a key holding the wrong kind of value"))) + return + } + + val, found := hash[field] + if !found { + conn.Write(serializeRESP(nil)) + return + } + + conn.Write(serializeRESP(val)) +} + +func handleHgetall(conn net.Conn, args []string){ + if len(args) != 2 { + conn.Write(serializeRESP(errors.New("ERR wrong number of arguments for 'HGETALL'"))) + return + } + key := args[1] + + db.mu.Lock() + defer db.mu.Unlock() + + item, exists := db.data[key] + if !exists { + conn.Write(serializeRESP(nil)) + return + } + + hash, ok := item.Value.(map[string]string) + if !ok { + conn.Write(serializeRESP(errors.New("WRONGTYPE Operation against a key holding the wrong kind of value"))) + return + } + conn.Write(serializeRESP(hash)) }
\ No newline at end of file @@ -29,6 +29,9 @@ var commandRegistry = map[string]handlerFunc{ "LPOP": handleLpop, "RPOP": handleRpop, "EXPIRE": handleExpire, + "HSET": handleHset, + "HGET": handleHget, + "HGETALL": handleHgetall, } func main() { @@ -36,6 +36,14 @@ func serializeRESP(v any) []byte { result = append(result, serializeRESP(val[i])...) } return result + case map[string]string: + size := len(val) + result := []byte(fmt.Sprintf("*%d\r\n", size*2)) + for key, value := range val { + result = append(result, serializeRESP(key)...) + result = append(result, serializeRESP(value)...) + } + return result case SimpleString: simpleStr := fmt.Sprintf("+%s\r\n", val) return []byte(simpleStr) |
