Implemented command that returns all the commands in the server

This commit is contained in:
Kelvin Clement Mwinuka
2024-02-26 05:31:38 +08:00
parent f7164cf305
commit b32292d8be
3 changed files with 107 additions and 2 deletions

View File

@@ -8,8 +8,61 @@ import (
"net"
)
func handleGetAllCommands(ctx context.Context, cmd []string, server utils.Server, _ *net.Conn) ([]byte, error) {
commands := server.GetAllCommands(ctx)
res := ""
commandCount := 0
for _, c := range commands {
if c.SubCommands == nil || len(c.SubCommands) <= 0 {
res += "*6\r\n"
// Command name
res += fmt.Sprintf("+command\r\n*1\r\n$%d\r\n%s\r\n", len(c.Command), c.Command)
// Command categories
res += fmt.Sprintf("+categories\r\n*%d\r\n", len(c.Categories))
for _, category := range c.Categories {
res += fmt.Sprintf("$%d\r\n%s\r\n", len(category), category)
}
// Description
res += fmt.Sprintf("+description\r\n*1\r\n$%d\r\n%s\r\n", len(c.Description), c.Description)
commandCount += 1
continue
}
// There are sub-commands
for _, sc := range c.SubCommands {
res += "*6\r\n"
// Command name
command := fmt.Sprintf("%s %s", c.Command, sc.Command)
res += fmt.Sprintf("+command\r\n*1\r\n$%d\r\n%s\r\n", len(command), command)
// Command categories
res += fmt.Sprintf("+categories\r\n*%d\r\n", len(sc.Categories))
for _, category := range sc.Categories {
res += fmt.Sprintf("$%d\r\n%s\r\n", len(category), category)
}
// Description
res += fmt.Sprintf("+description\r\n*1\r\n$%d\r\n%s\r\n", len(sc.Description), sc.Description)
commandCount += 1
}
}
res = fmt.Sprintf("*%d\r\n%s\r\n", commandCount, res)
return []byte(res), nil
}
func Commands() []utils.Command {
return []utils.Command{
{
Command: "commands",
Categories: []string{utils.AdminCategory, utils.SlowCategory},
Description: "Get a list of all the commands in available on the server with categories and descriptions",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
HandlerFunc: handleGetAllCommands,
},
{
Command: "save",
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},

View File

@@ -0,0 +1,31 @@
package admin
import (
"bytes"
"context"
"fmt"
"github.com/echovault/echovault/src/server"
"github.com/tidwall/resp"
"testing"
)
func Test_CommandsHandler(t *testing.T) {
mockServer := server.NewServer(server.Opts{
Commands: Commands(),
})
res, err := handleGetAllCommands(context.Background(), []string{"commands"}, mockServer, nil)
if err != nil {
t.Error(err)
}
rd := resp.NewReader(bytes.NewReader(res))
rv, _, err := rd.ReadValue()
if err != nil {
t.Error(err)
}
for _, element := range rv.Array() {
fmt.Println(element)
}
}

View File

@@ -225,8 +225,29 @@ func (server *Server) handleConnection(ctx context.Context, conn net.Conn) {
continue
}
if _, err = w.Write(res); err != nil {
log.Println(err)
chunkSize := 1024
if len(res) <= chunkSize {
_, err = w.Write(res)
if err != nil {
log.Println(err)
}
continue
}
// If the response is large, send it in chunks.
startIndex := 0
for {
// If the current start index is less than chunkSize from length, return the remaining bytes.
if len(res)-1-startIndex < chunkSize {
_, _ = w.Write(res[startIndex:])
break
}
n, _ := w.Write(res[startIndex : startIndex+chunkSize])
if n < chunkSize {
break
}
startIndex += chunkSize
}
}