aboutsummaryrefslogtreecommitdiff
path: root/handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'handlers.go')
-rw-r--r--handlers.go269
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))
+
+}