mirror of
https://github.com/EchoVault/SugarDB.git
synced 2025-10-13 11:43:55 +08:00
Added encoding function for integers.
Added functionality for mget.
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
@@ -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
112
server/cmd_functions.go
Normal 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)
|
||||
}
|
||||
}
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user