aboutsummaryrefslogtreecommitdiff
path: root/handlers.go
diff options
context:
space:
mode:
authoralex <[email protected]>2026-07-06 14:38:56 +0200
committeralex <[email protected]>2026-07-06 14:38:56 +0200
commit316b443addb7ec55e27f571ef489f2c19afb3a82 (patch)
treeb22dc242186b85b888cde0da002c8c95c0adcc99 /handlers.go
parent48df6e2f7c36a859e7d76de23017eef84452c0ed (diff)
downloadredis-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.go97
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