Added encoding function for integers.

Added functionality for mget.
This commit is contained in:
Kelvin Clement Mwinuka
2023-07-02 07:23:50 +08:00
parent c606353902
commit 04f0d92a95
4 changed files with 140 additions and 30 deletions

View File

@@ -2,8 +2,8 @@ package serialization
import (
"bytes"
"fmt"
"github.com/kelvinmwinuka/memstore/utils"
"github.com/tidwall/resp"
)
@@ -17,7 +17,7 @@ func Decode(raw string) ([]string, error) {
return nil, err
}
if v.Type().String() == "SimpleString" {
if utils.Contains[string]([]string{"SimpleString", "Integer"}, v.Type().String()) {
return []string{v.String()}, nil
}
@@ -27,6 +27,5 @@ func Decode(raw string) ([]string, error) {
}
}
fmt.Println(res)
return res, nil
}

View File

@@ -38,6 +38,27 @@ func encodeSimpleString(wr *resp.Writer, tokens []string) error {
}
}
func encodeInteger(wr *resp.Writer, tokens []string) error {
switch len(tokens) {
default:
return fmt.Errorf(wrong_args_error, strings.ToUpper(tokens[0]))
case 2:
num, err := strconv.ParseFloat(tokens[1], 32)
if err != nil {
return err
}
if !utils.IsInteger(num) {
return fmt.Errorf("value %f is not a valid integer", num)
}
wr.WriteInteger(int(num))
return nil
}
}
func encodeArray(wr *resp.Writer, tokens []string) error {
switch l := len(tokens); {
default:
@@ -186,6 +207,8 @@ func Encode(buf io.ReadWriter, comm string) error {
err = encodeIncr(wr, tokens)
case "simplestring":
err = encodeSimpleString(wr, tokens)
case "integer":
err = encodeInteger(wr, tokens)
case "array":
err = encodeArray(wr, tokens)
case "Error":

112
server/cmd_functions.go Normal file
View File

@@ -0,0 +1,112 @@
package main
import (
"bufio"
"fmt"
"strconv"
"strings"
"github.com/kelvinmwinuka/memstore/serialization"
"github.com/kelvinmwinuka/memstore/utils"
)
func processPing(cmd []string, connRW *bufio.ReadWriter) {
if len(cmd) == 1 {
serialization.Encode(connRW, "SimpleString PONG")
connRW.Write([]byte("\n"))
connRW.Flush()
}
if len(cmd) == 2 {
serialization.Encode(connRW, fmt.Sprintf("SimpleString \"%s\"", cmd[1]))
connRW.Write([]byte("\n"))
connRW.Flush()
}
}
func processSet(cmd []string, connRW *bufio.ReadWriter, server *Server) {
fmt.Println("Process set command")
server.data.mu.Lock()
defer server.data.mu.Unlock()
switch x := len(cmd); {
default:
fmt.Println("Wrong number of args for SET commands")
case x > 3:
server.data.data[cmd[1]] = strings.Join(cmd[2:], " ")
serialization.Encode(connRW, "SimpleString OK")
case x == 3:
val, err := strconv.ParseFloat(cmd[2], 32)
if err != nil {
server.data.data[cmd[1]] = cmd[2]
} else if !utils.IsInteger(val) {
server.data.data[cmd[1]] = val
} else {
server.data.data[cmd[1]] = int(val)
}
serialization.Encode(connRW, "SimpleString OK")
}
connRW.Write([]byte("\n"))
connRW.Flush()
}
func processGet(cmd []string, connRW *bufio.ReadWriter, server *Server) {
server.data.mu.Lock()
defer server.data.mu.Unlock()
// Use reflection to determine the type of the value and how to encode it
switch server.data.data[cmd[1]].(type) {
default:
fmt.Println("Error. The requested object's type cannot be returned with the GET command")
case string:
serialization.Encode(connRW, fmt.Sprintf("SimpleString \"%s\"", server.data.data[cmd[1]]))
case float64:
serialization.Encode(connRW, fmt.Sprintf("SimpleString %f", server.data.data[cmd[1]]))
case int:
serialization.Encode(connRW, fmt.Sprintf("Integer %d", server.data.data[cmd[1]]))
}
connRW.Write([]byte("\n"))
connRW.Flush()
}
func processMGet(cmd []string, connRW *bufio.ReadWriter, server *Server) {
server.data.mu.Lock()
defer server.data.mu.Unlock()
vals := []string{}
for _, key := range cmd[1:] {
switch server.data.data[key].(type) {
case string:
vals = append(vals, fmt.Sprintf("%s", server.data.data[key]))
case float64:
vals = append(vals, fmt.Sprintf("%f", server.data.data[key]))
case int:
vals = append(vals, fmt.Sprintf("%d", server.data.data[key]))
}
}
serialization.Encode(connRW, fmt.Sprintf("Array %s", strings.Join(vals, " ")))
connRW.Write([]byte("\n"))
connRW.Flush()
}
func processCommand(cmd []string, connRW *bufio.ReadWriter, server *Server) {
// Return encoded message to client
switch strings.ToLower(cmd[0]) {
default:
fmt.Println("The command is unknown")
case "ping":
processPing(cmd, connRW)
case "set":
processSet(cmd, connRW, server)
case "get":
processGet(cmd, connRW, server)
case "mget":
processMGet(cmd, connRW, server)
}
}

View File

@@ -7,7 +7,6 @@ import (
"io"
"net"
"net/http"
"strings"
"sync"
"github.com/kelvinmwinuka/memstore/serialization"
@@ -45,32 +44,7 @@ func (server *Server) handleConnection(conn net.Conn) {
serialization.Encode(connRW, fmt.Sprintf("Error %s", err.Error()))
continue
} else {
// Return encoded message to client
switch strings.ToLower(cmd[0]) {
default:
fmt.Println("The command is unknown")
case "ping":
if len(cmd) == 1 {
serialization.Encode(connRW, "SimpleString PONG")
connRW.Write([]byte("\n"))
connRW.Flush()
}
if len(cmd) == 2 {
serialization.Encode(connRW, fmt.Sprintf("SimpleString \"%s\"", cmd[1]))
connRW.Write([]byte("\n"))
connRW.Flush()
}
case "set":
fmt.Println("Set the value")
case "get":
fmt.Println("Get the value")
case "mget":
fmt.Println("Get the multiple values requested")
serialization.Encode(connRW, "Array THIS IS THE ARRAY")
connRW.Write([]byte("\n"))
connRW.Flush()
}
processCommand(cmd, connRW, server)
}
}
@@ -143,6 +117,8 @@ func (server *Server) StartHTTP() {
}
func (server *Server) Start() {
server.data.data = make(map[string]interface{})
conf := server.config
if conf.TLS && (len(conf.Key) <= 0 || len(conf.Cert) <= 0) {