diff options
| author | alex <[email protected]> | 2026-07-06 14:38:56 +0200 |
|---|---|---|
| committer | alex <[email protected]> | 2026-07-06 14:38:56 +0200 |
| commit | 316b443addb7ec55e27f571ef489f2c19afb3a82 (patch) | |
| tree | b22dc242186b85b888cde0da002c8c95c0adcc99 /handlers.go | |
| parent | 48df6e2f7c36a859e7d76de23017eef84452c0ed (diff) | |
| download | redis-clone-316b443addb7ec55e27f571ef489f2c19afb3a82.tar.xz redis-clone-316b443addb7ec55e27f571ef489f2c19afb3a82.zip | |
added struct Item and keyowrd EXPIRE so now we can track expire time of items in the db
Diffstat (limited to 'handlers.go')
| -rw-r--r-- | handlers.go | 97 |
1 files changed, 69 insertions, 28 deletions
diff --git a/handlers.go b/handlers.go index 885e348..244d332 100644 --- a/handlers.go +++ b/handlers.go @@ -4,6 +4,7 @@ import ( "errors" "net" "strconv" + "time" ) func handleGet(conn net.Conn, args []string) { @@ -18,13 +19,19 @@ func handleGet(conn net.Conn, args []string) { key := args[1] - value, exists := db.data[key] + item, exists := db.data[key] if !exists { conn.Write(serializeRESP(nil)) return } - strValue, ok := value.(string) + if item.ExpiresAt != nil && time.Now().After(*item.ExpiresAt) { + delete(db.data, key) + conn.Write(serializeRESP(nil)) + return + } + + strValue, ok := item.Value.(string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) @@ -65,9 +72,9 @@ func handleSet(conn net.Conn, args []string) { } key := args[1] - value := args[2] + item := Item{Value: args[2]} - db.data[key] = value + db.data[key] = item conn.Write(serializeRESP(SimpleString("OK"))) } @@ -104,9 +111,9 @@ func handleIncr(conn net.Conn, args []string) { key := args[1] - value, exists := db.data[key] + item, exists := db.data[key] if exists { - strValue, ok := value.(string) + strValue, ok := item.Value.(string) if !ok { err := errors.New("value is not an integer or out of range") conn.Write(serializeRESP(err)) @@ -121,10 +128,10 @@ func handleIncr(conn net.Conn, args []string) { } newValueStr := strconv.Itoa(currentInt + 1) - db.data[key] = newValueStr + db.data[key] = Item{Value: newValueStr} conn.Write(serializeRESP(currentInt + 1)) } else { - db.data[key] = "1" + db.data[key] = Item{Value: "1"} conn.Write(serializeRESP(1)) } } @@ -141,9 +148,9 @@ func handleDecr(conn net.Conn, args []string) { key := args[1] - value, exists := db.data[key] + item, exists := db.data[key] if exists { - strValue, ok := value.(string) + strValue, ok := item.Value.(string) if !ok { err := errors.New("value is not an integer or out of range") conn.Write(serializeRESP(err)) @@ -158,10 +165,10 @@ func handleDecr(conn net.Conn, args []string) { } newValueStr := strconv.Itoa(currentInt - 1) - db.data[key] = newValueStr + db.data[key] = Item{Value:newValueStr} conn.Write(serializeRESP(currentInt - 1)) } else { - db.data[key] = "-1" + db.data[key] = Item{Value: "-1"} conn.Write(serializeRESP(-1)) } } @@ -185,7 +192,7 @@ func handleFlushall(conn net.Conn, args []string) { return } - db.data = make(map[string]any) + db.data = make(map[string]Item) conn.Write(serializeRESP(SimpleString("OK"))) } @@ -197,11 +204,11 @@ func handleRpush(conn net.Conn, args []string) { defer db.mu.Unlock() var list []string - existingValue, exists := db.data[key] + existingItem, exists := db.data[key] if exists { var ok bool - list, ok = existingValue.([]string) + list, ok = existingItem.Value.([]string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) @@ -211,7 +218,7 @@ func handleRpush(conn net.Conn, args []string) { list = []string{} } list = append(list, newItems...) - db.data[key] = list + db.data[key] = Item{Value: list} conn.Write(serializeRESP(len(list))) } @@ -234,14 +241,20 @@ func handleLrange(conn net.Conn, args []string) { key := args[1] - value, exists := db.data[key] + item, exists := db.data[key] if !exists { conn.Write(serializeRESP([]string{})) return } - typedList, ok := value.([]string) + if item.ExpiresAt != nil && time.Now().After(*item.ExpiresAt) { + delete(db.data, key) + conn.Write(serializeRESP(nil)) + return + } + + typedList, ok := item.Value.([]string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) @@ -288,13 +301,13 @@ func handleLpop(conn net.Conn, args []string){ } key := args[1] - value, exists := db.data[key] + item, exists := db.data[key] if !exists { conn.Write(serializeRESP(nil)) return } - typedList, ok := value.([]string) + typedList, ok := item.Value.([]string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) @@ -306,14 +319,14 @@ func handleLpop(conn net.Conn, args []string){ return } - item := typedList[0] + newItem := typedList[0] newList := typedList[1:] if len(newList) <= 0 { delete(db.data, key) }else{ - db.data[key] = newList + db.data[key] = Item{Value: newList} } - conn.Write(serializeRESP(item)) + conn.Write(serializeRESP(newItem)) } @@ -328,13 +341,13 @@ func handleRpop(conn net.Conn, args []string){ } key := args[1] - value, exists := db.data[key] + item, exists := db.data[key] if !exists { conn.Write(serializeRESP(nil)) return } - typedList, ok := value.([]string) + typedList, ok := item.Value.([]string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) @@ -346,13 +359,41 @@ func handleRpop(conn net.Conn, args []string){ return } - item := typedList[len(typedList)-1] + newItem := typedList[len(typedList)-1] newList := typedList[:len(typedList)-1] if len(newList) <= 0 { delete(db.data, key) }else{ - db.data[key] = newList + db.data[key] = Item{Value: newList} } - conn.Write(serializeRESP(item)) + conn.Write(serializeRESP(newItem)) } + +func handleExpire(conn net.Conn, args []string){ + + if len(args) != 3 { + conn.Write(serializeRESP(errors.New("wrong number of arguments for 'EXPIRE'"))) + return + } + + key := args[1] + seconds, err := strconv.Atoi(args[2]) + if err != nil { + conn.Write(serializeRESP(errors.New("ERR value is not an integer"))) + return + } + db.mu.Lock() + defer db.mu.Unlock() + + item, exists := db.data[key] + if !exists { + conn.Write(serializeRESP(0)) // Key doesn't exist + return + } + + expiry := time.Now().Add(time.Duration(seconds) * time.Second) + item.ExpiresAt = &expiry + db.data[key] = item + conn.Write(serializeRESP(1)) +}
\ No newline at end of file |
