package main
import (
"errors"
"net"
"path/filepath"
"sort"
"strconv"
"time"
)
func handleGet(conn net.Conn, args []string) {
db.mu.Lock()
defer db.mu.Unlock()
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'GET'")
conn.Write(serializeRESP(err))
return
}
key := args[1]
item, exists := db.data[key]
if !exists {
conn.Write(serializeRESP(nil))
return
}
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))
return
}
conn.Write(serializeRESP(strValue))
}
func handleExists(conn net.Conn, args []string) {
db.mu.Lock()
defer db.mu.Unlock()
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'EXISTS'")
conn.Write(serializeRESP(err))
return
}
key := args[1]
_, exists := db.data[key]
if exists {
conn.Write(serializeRESP(1))
} else {
conn.Write(serializeRESP(0))
}
}
func handleSet(conn net.Conn, args []string) {
db.mu.Lock()
defer db.mu.Unlock()
if len(args) != 3 {
err := errors.New("wrong number of arguments for 'SET'")
conn.Write(serializeRESP(err))
return
}
key := args[1]
item := Item{Value: args[2]}
db.data[key] = item
conn.Write(serializeRESP(SimpleString("OK")))
}
func handleDel(conn net.Conn, args []string) {
db.mu.Lock()
defer db.mu.Unlock()
if len(args) < 2 {
err := errors.New("wrong number of arguments for 'DEL'")
conn.Write(serializeRESP(err))
return
}
deletedKeys := 0
for i := 1; i<len(args);i++{
_, exists := db.data[args[i]]
if exists {
delete(db.data, args[i])
deletedKeys += 1
}
}
conn.Write(serializeRESP(deletedKeys))
}
func handleIncr(conn net.Conn, args []string) {
db.mu.Lock()
defer db.mu.Unlock()
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'INCR'")
conn.Write(serializeRESP(err))
return
}
key := args[1]
item, exists := db.data[key]
if exists {
strValue, ok := item.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] = Item{Value: newValueStr}
conn.Write(serializeRESP(currentInt + 1))
} else {
db.data[key] = Item{Value: "1"}
conn.Write(serializeRESP(1))
}
}
func handleDecr(conn net.Conn, args []string) {
db.mu.Lock()
defer db.mu.Unlock()
if len(args) != 2 {
err := errors.New("wrong number of arguments for 'DECR'")
conn.Write(serializeRESP(err))
return
}
key := args[1]
item, exists := db.data[key]
if exists {
strValue, ok := item.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] = Item{Value:newValueStr}
conn.Write(serializeRESP(currentInt - 1))
} else {
db.data[key] = Item{Value: "-1"}
conn.Write(serializeRESP(-1))
}
}
func handlePing(conn net.Conn, args []string) {
if len(args) != 1 {
err :=