diff options
| author | alex <[email protected]> | 2026-07-06 13:35:07 +0200 |
|---|---|---|
| committer | alex <[email protected]> | 2026-07-06 13:35:07 +0200 |
| commit | f00398f4be24b5c3cce52c36dc71a42d1d0ccfbe (patch) | |
| tree | 1459c3502db09b664d3ceac114b2c86affd09d11 /handlers.go | |
| parent | 8c49e03997128de4761acaaa6606d58f87d92c6c (diff) | |
| download | redis-clone-f00398f4be24b5c3cce52c36dc71a42d1d0ccfbe.tar.xz redis-clone-f00398f4be24b5c3cce52c36dc71a42d1d0ccfbe.zip | |
split the code into multiple files for better readability
Diffstat (limited to 'handlers.go')
| -rw-r--r-- | handlers.go | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/handlers.go b/handlers.go new file mode 100644 index 0000000..4625f6a --- /dev/null +++ b/handlers.go @@ -0,0 +1,269 @@ +package main + +import ( + "errors" + "net" + "strconv" +) + +func handleGet(conn net.Conn, key string) { + db.mu.Lock() + defer db.mu.Unlock() + + value, exists := db.data[key] + if !exists { + conn.Write(serializeRESP(nil)) + return + } + + strValue, ok := value.(string) + if !ok { + err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") + conn.Write(serializeRESP(err)) + return + } + + conn.Write(serializeRESP(strValue)) +} + +func handleExists(conn net.Conn, key string) { + db.mu.Lock() + defer db.mu.Unlock() + + _, exists := db.data[key] + if exists { + conn.Write(serializeRESP(1)) + } else { + conn.Write(serializeRESP(0)) + } +} + +func handleSet(conn net.Conn, key, value string) { + db.mu.Lock() + defer db.mu.Unlock() + + db.data[key] = value + conn.Write(serializeRESP(SimpleString("OK"))) +} + +func handleDel(conn net.Conn, key string) { + db.mu.Lock() + defer db.mu.Unlock() + + _, exists := db.data[key] + if exists { + delete(db.data, key) + conn.Write(serializeRESP(1)) + } else { + conn.Write(serializeRESP(0)) + } +} + +func handleIncr(conn net.Conn, key string) { + db.mu.Lock() + defer db.mu.Unlock() + + value, exists := db.data[key] + if exists { + strValue, ok := value.(string) + if !ok { + err := errors.New("value is not an integer or out of range") + conn.Write(serializeRESP(err)) + return + } + + currentInt, err := strconv.Atoi(strValue) + if err != nil { + err := errors.New("value is not an integer or out of range") + conn.Write(serializeRESP(err)) + return + } + + newValueStr := strconv.Itoa(currentInt + 1) + db.data[key] = newValueStr + conn.Write(serializeRESP(currentInt + 1)) + } else { + db.data[key] = "1" + conn.Write(serializeRESP(1)) + } +} + +func handleDecr(conn net.Conn, key string) { + db.mu.Lock() + defer db.mu.Unlock() + + value, exists := db.data[key] + if exists { + strValue, ok := value.(string) + if !ok { + err := errors.New("value is not an integer or out of range") + conn.Write(serializeRESP(err)) + return + } + + currentInt, err := strconv.Atoi(strValue) + if err != nil { + err := errors.New("value is not an integer or out of range") + conn.Write(serializeRESP(err)) + return + } + + newValueStr := strconv.Itoa(currentInt - 1) + db.data[key] = newValueStr + conn.Write(serializeRESP(currentInt - 1)) + } else { + db.data[key] = "-1" + conn.Write(serializeRESP(-1)) + } +} + +func handlePing(conn net.Conn) { + conn.Write(serializeRESP(SimpleString("PONG"))) +} + +func handleFlushall(conn net.Conn) { + db.mu.Lock() + defer db.mu.Unlock() + + db.data = make(map[string]any) + conn.Write(serializeRESP(SimpleString("OK"))) +} + +func handleRpush(conn net.Conn, args []string) { + key := args[1] + newItems := args[2:] + + db.mu.Lock() + defer db.mu.Unlock() + + var list []string + existingValue, exists := db.data[key] + + if exists { + var ok bool + list, ok = existingValue.([]string) + if !ok { + err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") + conn.Write(serializeRESP(err)) + return + } + } else { + list = []string{} + } + list = append(list, newItems...) + db.data[key] = list + conn.Write(serializeRESP(len(list))) +} + +func handleLrange(conn net.Conn, key string, start, stop int) { + db.mu.Lock() + defer db.mu.Unlock() + + value, exists := db.data[key] + if !exists { + conn.Write(serializeRESP([]string{})) + + return + } + + typedList, ok := value.([]string) + if !ok { + err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") + conn.Write(serializeRESP(err)) + return + } + + size := len(typedList) + + if start < 0 { + start += size + if start < 0 { + start = 0 + } + } + + if stop < 0 { + stop += size + if stop < 0 { + stop = 0 + } + } + + if stop >= size { + stop = size - 1 + } + + if start > stop || start >= size { + conn.Write(serializeRESP([]string{})) + return + } + + resultList := typedList[start : stop+1] + conn.Write(serializeRESP(resultList)) +} + +func handleLpop(conn net.Conn, key string){ + db.mu.Lock() + defer db.mu.Unlock() + + value, exists := db.data[key] + if !exists { + conn.Write(serializeRESP(nil)) + return + } + + typedList, ok := value.([]string) + if !ok { + err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") + conn.Write(serializeRESP(err)) + return + } + + if len(typedList) == 0 { + conn.Write(serializeRESP(nil)) + return + } + + item := typedList[0] + newList := typedList[1:] + if len(newList) <= 0 { + delete(db.data, key) + }else{ + db.data[key] = newList + } + conn.Write(serializeRESP(item)) + +} + +func handleRpop(conn net.Conn, key string){ + db.mu.Lock() + defer db.mu.Unlock() + + value, exists := db.data[key] + if !exists { + conn.Write(serializeRESP(nil)) + return + } + + typedList, ok := value.([]string) + if !ok { + err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") + conn.Write(serializeRESP(err)) + return + } + + if len(typedList) == 0 { + conn.Write(serializeRESP(nil)) + return + } + + item := typedList[len(typedList)-1] + newList := typedList[:len(typedList)-1] + if len(newList) <= 0 { + delete(db.data, key) + }else{ + db.data[key] = newList + } + conn.Write(serializeRESP(item)) + +} |
