Files
SugarDB/src/modules/get/commands.go

128 lines
2.7 KiB
Go

package get
import (
"context"
"errors"
"fmt"
"github.com/kelvinmwinuka/memstore/src/utils"
"net"
"strings"
)
type Plugin struct {
name string
commands []utils.Command
categories []string
description string
}
var GetModule Plugin
func (p Plugin) Name() string {
return p.name
}
func (p Plugin) Commands() []utils.Command {
return p.commands
}
func (p Plugin) Description() string {
return p.description
}
func (p Plugin) HandleCommand(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
switch strings.ToLower(cmd[0]) {
default:
return nil, errors.New("command unknown")
case "get":
return handleGet(ctx, cmd, server)
case "mget":
return handleMGet(ctx, cmd, server)
}
}
func handleGet(ctx context.Context, cmd []string, s utils.Server) ([]byte, error) {
if len(cmd) != 2 {
return nil, errors.New("wrong number of args for GET command")
}
key := cmd[1]
s.KeyRLock(ctx, key)
value := s.GetValue(key)
s.KeyRUnlock(key)
switch value.(type) {
default:
return []byte(fmt.Sprintf("+%v\r\n\n", value)), nil
case nil:
return []byte("+nil\r\n\n"), nil
}
}
func handleMGet(ctx context.Context, cmd []string, s utils.Server) ([]byte, error) {
if len(cmd) < 2 {
return nil, errors.New("wrong number of args for MGET command")
}
vals := []string{}
for _, key := range cmd[1:] {
func(key string) {
s.KeyRLock(ctx, key)
switch s.GetValue(key).(type) {
default:
vals = append(vals, fmt.Sprintf("%v", s.GetValue(key)))
case nil:
vals = append(vals, "nil")
}
s.KeyRUnlock(key)
}(key)
}
bytes := []byte(fmt.Sprintf("*%d\r\n", len(vals)))
for _, val := range vals {
bytes = append(bytes, []byte(fmt.Sprintf("$%d\r\n%s\r\n", len(val), val))...)
}
bytes = append(bytes, []byte("\n")...)
return bytes, nil
}
func NewModule() Plugin {
GetModule := Plugin{
name: "GetCommands",
commands: []utils.Command{
{
Command: "get",
Categories: []string{utils.ReadCategory, utils.FastCategory},
Description: "(GET key) Get the value at the specified key.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New("wrong number of arguments")
}
return []string{cmd[1]}, nil
},
},
{
Command: "mget",
Categories: []string{utils.ReadCategory, utils.FastCategory},
Description: "(MGET key1 [key2]) Get multiple values from the specified keys.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New("wrong number of arguments")
}
return cmd[1:], nil
},
},
},
description: "Handle basic GET and MGET commands",
}
return GetModule
}