diff --git a/go.mod b/go.mod index 47ef8d0..26906be 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,8 @@ module server go 1.22.5 -require github.com/dicedb/go-dice v0.0.0-20240820180649-d97f15fca831 - require ( - github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dicedb/go-dice v0.0.0-20240820180649-d97f15fca831 // indirect ) diff --git a/go.sum b/go.sum index 8be4df2..af5b6c5 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= diff --git a/internal/api/api.go b/internal/api/api.go index 62c7920..ff8e2c8 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -3,6 +3,9 @@ package api import ( "encoding/json" "net/http" + + "server/internal/db" + helpers "server/pkg/util" ) func JSONResponse(w http.ResponseWriter, r *http.Request, status int, data interface{}) { @@ -10,12 +13,13 @@ func JSONResponse(w http.ResponseWriter, r *http.Request, status int, data inter w.WriteHeader(status) if err := json.NewEncoder(w).Encode(data); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) + return } } func RegisterRoutes(mux *http.ServeMux) { mux.HandleFunc("/health", HealthCheck) - mux.HandleFunc("/cli", cliHandler) + mux.HandleFunc("/cli/{cmd}", cliHandler) mux.HandleFunc("/search", searchHandler) } @@ -24,7 +28,14 @@ func HealthCheck(w http.ResponseWriter, r *http.Request) { } func cliHandler(w http.ResponseWriter, r *http.Request) { - JSONResponse(w, r, http.StatusOK, map[string]string{"message": "cli handler"}) + diceCmds, err := helpers.ParseHTTPRequest(r) + if err != nil { + http.Error(w, "Error parsing HTTP request", http.StatusBadRequest) + return + } + + resp := db.ExecuteCommand(diceCmds) + JSONResponse(w, r, http.StatusOK, resp) } func searchHandler(w http.ResponseWriter, r *http.Request) { diff --git a/internal/cmds/cmds.go b/internal/cmds/cmds.go new file mode 100644 index 0000000..6470d27 --- /dev/null +++ b/internal/cmds/cmds.go @@ -0,0 +1,12 @@ +package cmds + +type CommandRequest struct { + Cmd string `json:"cmd"` + Args CommandRequestArgs +} + +type CommandRequestArgs struct { + Key string `json:"key"` + Value string `json:"value,omitempty"` + Keys []string `json:"keys,omitempty"` +} diff --git a/internal/db/commands.go b/internal/db/commands.go new file mode 100644 index 0000000..ef98960 --- /dev/null +++ b/internal/db/commands.go @@ -0,0 +1,16 @@ +package db + +func getKey(key string) (string, error) { + val, err := rdb.Get(ctx, key).Result() + return val, err +} + +func setKey(key, value string) error { + err := rdb.Set(ctx, key, value, 0).Err() + return err +} + +func deleteKeys(keys []string) error { + err := rdb.Del(ctx, keys...).Err() + return err +} diff --git a/internal/db/dicedb.go b/internal/db/dicedb.go index 1bd5450..a000de8 100644 --- a/internal/db/dicedb.go +++ b/internal/db/dicedb.go @@ -3,3 +3,62 @@ this will be the DiceDB client */ package db + +import ( + "context" + "log" + "server/internal/cmds" + + dice "github.com/dicedb/go-dice" +) + +var rdb *dice.Client +var ctx = context.Background() + +func CloseDiceDB() { + err := rdb.Close() + if err != nil { + log.Fatalf("error closing DiceDB connection: %v", err) + } +} + +func errorResponse(response string) map[string]string { + return map[string]string{"error": response} +} + +func ExecuteCommand(command *cmds.CommandRequest) interface{} { + switch command.Cmd { + case "get": + if command.Args.Key == "" { + return errorResponse("key is required") + } + val, err := getKey(command.Args.Key) + if err != nil { + return errorResponse("error running get command") + } + return map[string]string{"value": val} + + case "set": + if command.Args.Key == "" || command.Args.Value == "" { + return errorResponse("key and value are required") + } + err := setKey(command.Args.Key, command.Args.Value) + if err != nil { + return errorResponse("failed to set key") + } + return map[string]string{"result": "OK"} + + case "del": + if len(command.Args.Keys) == 0 { + return map[string]string{"error": "atleast one key is required"} + } + err := deleteKeys(command.Args.Keys) + if err != nil { + return map[string]string{"error": "failed to delete keys"} + } + + return map[string]string{"result": "OK"} + default: + return errorResponse("unknown command") + } +} diff --git a/pkg/util/helpers.go b/pkg/util/helpers.go index 345b806..1613bf2 100644 --- a/pkg/util/helpers.go +++ b/pkg/util/helpers.go @@ -1 +1,33 @@ package helpers + +import ( + "encoding/json" + "errors" + "io" + "log" + "net/http" + "server/internal/cmds" +) + +func ParseHTTPRequest(r *http.Request) (*cmds.CommandRequest, error) { + command := r.PathValue("cmd") + if command == "" { + return nil, errors.New("invalid command") + } + + body, err := io.ReadAll(r.Body) + if err != nil { + log.Fatalf("error reading body: %v", err) + } + + var commandRequestArgs *cmds.CommandRequestArgs + err = json.Unmarshal(body, &commandRequestArgs) + if err != nil { + log.Fatalf("error unmarshalling body: %v", err) + } + + return &cmds.CommandRequest{ + Cmd: command, + Args: *commandRequestArgs, + }, nil +}