aboutsummaryrefslogtreecommitdiff
path: root/handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'handlers.go')
-rw-r--r--handlers.go672
1 files changed, 0 insertions, 672 deletions
diff --git a/handlers.go b/handlers.go
deleted file mode 100644
index 1569771..0000000
--- a/handlers.go
+++ /dev/null
@@ -1,672 +0,0 @@
-package main
-
-import (
- "errors"
- "net"
- "path/filepath"
- "redisClone/pkg/core"
- "sort"
- "strconv"
- "time"
-)
-
-func handleGet(args []string)interface{} {
- if len(args) != 2 {
- err := errors.New("wrong number of arguments for 'GET'")
- return err
- }
-
- key := args[1]
-
- result := db.ExecuteRead(key, func(s *core.Shard) interface{}{
- item, exists := s.Data[key]
- if !exists {
- return nil
- }
-
- if item.ExpiresAt != nil && time.Now().After(*item.ExpiresAt) {
- delete(s.Data, key)
- return nil
- }
-
- strValue, ok := item.Value.(string)
- if !ok {
- err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- return err
- }
- return strValue
- })
-
- return result
-}
-
-func handleExists(args []string)interface{} {
- if len(args) != 2 {
- err := errors.New("wrong number of arguments for 'EXISTS'")
- return err
- }
-
- key := args[1]
- result := db.ExecuteRead(key, func(s *core.Shard) interface{}{
- _, exists := s.Data[key]
- if exists {
- return 1
- } else {
- return 0
- }
- })
-
- return result
-}
-
-func handleSet(args []string)interface{} {
- if len(args) != 3 {
- err := errors.New("wrong number of arguments for 'SET'")
- return err
- }
-
- key := args[1]
- result := db.Execute(key, func(s *core.Shard) interface{}{
- item := core.Item{Value: args[2]}
- s.Data[key] = item
- return core.SimpleString("OK")
- })
-
- return result
-}
-
-func handleDel(args []string)interface{} {
-
- if len(args) < 2 {
- err := errors.New("wrong number of arguments for 'DEL'")
- return err
- }
- keys := args[1:]
- deletedKeys := db.ExecuteMulti(keys, func(shards []*core.Shard) interface{}{
- count := 0
- for _, key := range keys{
- shard := db.GetShard(key)
- _, exists := shard.Data[key]
- if exists {
- delete(shard.Data, key)
- count += 1
- }
- }
- return count
- })
-
- return deletedKeys
-}
-
-
-func handleIncr(args []string)interface{} {
-
- if len(args) != 2 {
- err := errors.New("wrong number of arguments for 'INCR'")
- return err
- }
-
- key := args[1]
- result := db.Execute(key, func(s *core.Shard)interface{}{
- item, exists := s.Data[key]
- if exists {
- strValue, ok := item.Value.(string)
- if !ok {
- err := errors.New("value is not an integer or out of range")
- return err
- }
-
- currentInt, err := strconv.Atoi(strValue)
- if err != nil {
- err := errors.New("value is not an integer or out of range")
- return err
- }
-
- newValueStr := strconv.Itoa(currentInt + 1)
- s.Data[key] = core.Item{Value: newValueStr}
- return currentInt + 1
- } else {
- s.Data[key] = core.Item{Value: "1"}
- return 1
- }
-
- })
-
- return result
-}
-
-func handleDecr(args []string)interface{} {
-
- if len(args) != 2 {
- err := errors.New("wrong number of arguments for 'DECR'")
- return err
- }
-
- key := args[1]
- result := db.Execute(key, func(s *core.Shard)interface{}{
- item, exists := s.Data[key]
- if exists {
- strValue, ok := item.Value.(string)
- if !ok {
- err := errors.New("value is not an integer or out of range")
- return err
- }
-
- currentInt, err := strconv.Atoi(strValue)
- if err != nil {
- err := errors.New("value is not an integer or out of range")
- return err
- }
-
- newValueStr := strconv.Itoa(currentInt + 1)
- s.Data[key] = core.Item{Value: newValueStr}
- return currentInt - 1
- } else {
- s.Data[key] = core.Item{Value: "1"}
- return -1
- }
-
- })
- return result
-}
-
-func handlePing(conn net.Conn, args []string) {
- conn.Write(core.SerializeRESP(core.SimpleString("OK")))
-}
-
-func handleFlushall(args []string)interface{} {
- if len(args) != 1 {
- err := errors.New("wrong number of arguments for 'FLUSHALL'")
- return err
- }
- result := db.ExecuteAll(func(shards []*core.Shard)interface{}{
- for _, shard := range shards{
- shard.Data = make(map[string]core.Item)
- }
- return core.SimpleString("OK")
- })
- return result
-}
-
-func handleRename(args []string)interface{}{
- if len(args) != 3 {
- err := errors.New("wrong number of arguments for 'RENAME'")
- return err
- }
- keys := args[1:]
-
- result := db.ExecuteMulti(keys,func(shards []*core.Shard)interface{}{
- item, exists := db.GetShard(keys[0]).Data[keys[0]]
- if !exists {
-
- return errors.New("no such key")
- }
-
- db.GetShard(keys[1]).Data[keys[1]] = item
- delete(db.GetShard(keys[0]).Data, keys[0])
-
- return core.SimpleString("OK")
- })
- return result
-}
-
-func handleRpush(args []string)interface{} {
- if len(args) < 3 {
- err := errors.New("wrong number of arguments for 'RPUSH'")
- return err
- }
- key := args[1]
- newItems := args[2:]
-
- result := db.Execute(key, func(s *core.Shard) interface{} {
- var list []string
- existingItem, exists := s.Data[key]
- if exists {
- var ok bool
- list, ok = existingItem.Value.([]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- } else {
- list = []string{}
- }
- list = append(list, newItems...)
- s.Data[key] = core.Item{Value: list}
- return len(list)
- })
- return result
-}
-
-func handleLpush(args []string)interface{} {
- if len(args) < 3 {
- err := errors.New("wrong number of arguments for 'LPUSH'")
- return err
- }
- key := args[1]
- newItems := args[2:]
-
- result := db.Execute(key, func(s *core.Shard) interface{} {
- var list []string
- existingItem, exists := s.Data[key]
- if exists {
- var ok bool
- list, ok = existingItem.Value.([]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- } else {
- list = []string{}
- }
- list = append(newItems, list...)
- s.Data[key] = core.Item{Value: list}
- return len(list)
- })
-
- return result
-}
-
-func handleLrange(args []string)interface{} {
- if len(args) != 4 {
- err := errors.New("wrong number of arguments for 'LRANGE'")
- return err
- }
- start, err1 := strconv.Atoi(args[2])
- stop, err2 := strconv.Atoi(args[3])
- if err1 != nil || err2 != nil {
- err := errors.New("value is not an integer or out of range")
- return err
- }
- key := args[1]
-
- result := db.ExecuteRead(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return []string{}
- }
- if item.ExpiresAt != nil && time.Now().After(*item.ExpiresAt) {
- delete(s.Data, key)
- return nil
- }
- typedList, ok := item.Value.([]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- 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 {
- return []string{}
- }
- return typedList[start : stop+1]
- })
- return result
-}
-
-func handleLpop(args []string)interface{} {
- if len(args) != 2 {
- err := errors.New("wrong number of arguments for 'LPOP'")
- return err
- }
- key := args[1]
-
- result := db.Execute(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return nil
- }
- typedList, ok := item.Value.([]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- if len(typedList) == 0 {
- return nil
- }
- newItem := typedList[0]
- newList := typedList[1:]
- if len(newList) <= 0 {
- delete(s.Data, key)
- } else {
- s.Data[key] = core.Item{Value: newList}
- }
- return newItem
- })
- return result
-}
-
-func handleRpop(args []string)interface{} {
- if len(args) != 2 {
- err := errors.New("wrong number of arguments for 'RPOP'")
- return err
- }
- key := args[1]
-
- result := db.Execute(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return nil
- }
- typedList, ok := item.Value.([]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- if len(typedList) == 0 {
- return nil
- }
- newItem := typedList[len(typedList)-1]
- newList := typedList[:len(typedList)-1]
- if len(newList) <= 0 {
- delete(s.Data, key)
- } else {
- s.Data[key] = core.Item{Value: newList}
- }
- return newItem
- })
- return result
-}
-
-func handleExpire(args []string)interface{} {
- if len(args) != 3 {
- return errors.New("wrong number of arguments for 'EXPIRE'")
- }
- key := args[1]
- seconds, err := strconv.Atoi(args[2])
- if err != nil {
- return errors.New("value is not an integer")
- }
-
- result := db.Execute(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return 0
- }
- expiry := time.Now().Add(time.Duration(seconds) * time.Second)
- item.ExpiresAt = &expiry
- s.Data[key] = item
- return 1
- })
- return result
-}
-
-func handleHset(args []string)interface{}{
- if len(args) < 4 || (len(args)-2)%2 != 0 {
- err := errors.New("wrong number of arguments for 'HSET'")
- return err
- }
- key := args[1]
-
- result := db.Execute(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- var hash map[string]string
- if exists {
- var ok bool
- hash, ok = item.Value.(map[string]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- } else {
- hash = make(map[string]string)
- }
- count := 0
- for i := 2; i < len(args); i += 2 {
- hash[args[i]] = args[i+1]
- count++
- }
- s.Data[key] = core.Item{Value: hash}
- return count
- })
- return result
-}
-
-func handleHget(args []string)interface{} {
- if len(args) != 3 {
- return errors.New("wrong number of arguments for 'HGET'")
- }
- key := args[1]
- field := args[2]
-
- result := db.ExecuteRead(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return nil
- }
- hash, ok := item.Value.(map[string]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- val, found := hash[field]
- if !found {
- return nil
- }
- return val
- })
- return result
-}
-
-func handleHgetall(args []string)interface{} {
- if len(args) != 2 {
- return errors.New("wrong number of arguments for 'HGETALL'")
- }
- key := args[1]
-
- result := db.ExecuteRead(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return nil
- }
- hash, ok := item.Value.(map[string]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- return hash
- })
- return result
-}
-
-func handleHkeys(args []string)interface{} {
- if len(args) != 2 {
- return errors.New("wrong number of arguments for 'HKEYS'")
- }
- key := args[1]
-
- result := db.ExecuteRead(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return nil
- }
- hash, ok := item.Value.(map[string]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- keys := make([]string, 0, len(hash))
- for k := range hash {
- keys = append(keys, k)
- }
- return keys
- })
- return result
-}
-
-func handleHvalues(args []string)interface{} {
- if len(args) != 2 {
- return errors.New("wrong number of arguments for 'HVALUES'")
- }
- key := args[1]
-
- result := db.ExecuteRead(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return nil
- }
- hash, ok := item.Value.(map[string]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
- values := make([]string, 0, len(hash))
- for _, v := range hash {
- values = append(values, v)
- }
- return values
- })
- return result
-}
-
-func handleType(args []string)interface{} {
- if len(args) != 2 {
- return errors.New("wrong number of arguments for 'TYPE'")
- }
- key := args[1]
-
- result := db.ExecuteRead(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return core.SimpleString("none")
- }
- switch item.Value.(type) {
- case string:
- return core.SimpleString("string")
- case []string:
- return core.SimpleString("list")
- case map[string]string:
- return core.SimpleString("hash")
- default:
- return core.SimpleString("unknown")
- }
- })
- return result
-}
-
-func handleDbsize(args []string)interface{} {
- if len(args) != 1 {
- return errors.New("wrong number of arguments for 'DBSIZE'")
- }
- result := db.ExecuteReadAll(func(shards []*core.Shard) interface{} {
- count := 0
- for _, shard := range shards {
- count += len(shard.Data)
- }
- return count
- })
- return result
-}
-
-func handleKeys(args []string)interface{} {
- if len(args) < 2 || len(args) > 3 {
- return errors.New("wrong number of arguments for 'KEYS'")
- }
- pattern := args[1]
- limit := -1
- if len(args) == 3 {
- val, err := strconv.Atoi(args[2])
- if err != nil {
- return errors.New("value is not an integer")
- }
- limit = val
- }
-
- result := db.ExecuteReadAll(func(shards []*core.Shard) interface{} {
- var matches []string
- for _, shard := range shards {
- for key := range shard.Data {
- matched, err := filepath.Match(pattern, key)
- if err != nil {
- return errors.New("illegal glob pattern")
- }
- if matched {
- matches = append(matches, key)
- }
- }
- }
- sort.Strings(matches)
- if limit != -1 && len(matches) > limit {
- matches = matches[:limit]
- }
- return matches
- })
- return result
-}
-
-func handleLrem(args []string)interface{} {
- if len(args) != 4 {
- return errors.New("wrong number of arguments for 'LREM'")
- }
- key := args[1]
- count, err := strconv.Atoi(args[2])
- toBeRemoved := args[3]
- if err != nil {
- return errors.New("value is not an integer")
- }
-
- result := db.Execute(key, func(s *core.Shard) interface{} {
- item, exists := s.Data[key]
- if !exists {
- return 0
- }
- list, ok := item.Value.([]string)
- if !ok {
- return errors.New("WRONGTYPE Operation against a key holding the wrong kind of value")
- }
-
- counter := 0
- absCount := count
- if count < 0 {
- absCount = -count
- }
-
- var newList []string
- if count == 0 {
- newList = []string{}
- for _, value := range list {
- if value == toBeRemoved {
- counter++
- } else {
- newList = append(newList, value)
- }
- }
- } else if count > 0 {
- newList = []string{}
- for _, value := range list {
- if value == toBeRemoved && counter < absCount {
- counter++
- } else {
- newList = append(newList, value)
- }
- }
- } else { // count < 0
- reversedNewList := []string{}
- for i := len(list) - 1; i >= 0; i-- {
- value := list[i]
- if value == toBeRemoved && counter < absCount {
- counter++
- } else {
- reversedNewList = append(reversedNewList, value)
- }
- }
- newList = make([]string, len(reversedNewList))
- for i, v := range reversedNewList {
- newList[len(reversedNewList)-1-i] = v
- }
- }
-
- if len(newList) == 0 {
- delete(s.Data, key)
- } else {
- item.Value = newList
- s.Data[key] = item
- }
- return counter
- })
- return result
-} \ No newline at end of file