diff --git a/cmd/main.go b/cmd/main.go index d0ce2c0b..a36f0fd7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -16,9 +16,9 @@ package main import ( "context" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/echovault" "log" "os" "os/signal" diff --git a/docker-compose.yaml b/docker-compose.yaml index 46c4de3c..cdecdb01 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -21,7 +21,7 @@ services: - TLS=false - MTLS=false - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml + # - ACL_CONFIG=/etc/config/echovault/acl.yml - REQUIRE_PASS=false - PASSWORD=password1 - FORWARD_COMMAND=false @@ -44,7 +44,7 @@ services: - "7946:7946" - "7999:8000" volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml + - ./volumes/config/acl.yml:/etc/config/echovault/acl.yml - ./volumes/standalone_node:/var/lib/echovault networks: - testnet @@ -65,7 +65,7 @@ services: - TLS=false - MTLS=false - BOOTSTRAP_CLUSTER=true - - ACL_CONFIG=/etc/config/echovault/acl.yml + # - ACL_CONFIG=/etc/config/echovault/acl.yml - REQUIRE_PASS=false - FORWARD_COMMAND=true - SNAPSHOT_THRESHOLD=1000 @@ -87,7 +87,7 @@ services: - "7945:7946" - "8000:8000" volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml + - ./volumes/config/acl.yml:/etc/config/echovault/acl.yml - ./volumes/cluster_node_1:/var/lib/echovault networks: - testnet @@ -108,7 +108,7 @@ services: - TLS=false - MTLS=false - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml + # - ACL_CONFIG=/etc/config/echovault/acl.yml - REQUIRE_PASS=false - FORWARD_COMMAND=true - SNAPSHOT_THRESHOLD=1000 @@ -130,7 +130,7 @@ services: - "7947:7946" - "8001:8000" volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml + - ./volumes/config/acl.yml:/etc/config/echovault/acl.yml - ./volumes/cluster_node_2:/var/lib/echovault networks: - testnet @@ -151,7 +151,7 @@ services: - TLS=false - MTLS=false - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml + # - ACL_CONFIG=/etc/config/echovault/acl.yml - REQUIRE_PASS=false - FORWARD_COMMAND=true - SNAPSHOT_THRESHOLD=1000 @@ -173,7 +173,7 @@ services: - "7948:7946" - "8002:8000" volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml + - ./volumes/config/acl.yml:/etc/config/echovault/acl.yml - ./volumes/cluster_node_3:/var/lib/echovault networks: - testnet @@ -194,7 +194,7 @@ services: - TLS=false - MTLS=false - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml + # - ACL_CONFIG=/etc/config/echovault/acl.yml - REQUIRE_PASS=false - FORWARD_COMMAND=true - SNAPSHOT_THRESHOLD=1000 @@ -216,7 +216,7 @@ services: - "7949:7946" - "8003:8000" volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml + - ./volumes/config/acl.yml:/etc/config/echovault/acl.yml - ./volumes/cluster_node_4:/var/lib/echovault networks: - testnet @@ -237,7 +237,7 @@ services: - TLS=false - MTLS=false - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml + # - ACL_CONFIG=/etc/config/echovault/acl.yml - REQUIRE_PASS=false - FORWARD_COMMAND=true - SNAPSHOT_THRESHOLD=1000 @@ -259,7 +259,7 @@ services: - "7950:7946" - "8004:8000" volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml + - ./volumes/config/acl.yml:/etc/config/echovault/acl.yml - ./volumes/cluster_node_5:/var/lib/echovault networks: - testnet \ No newline at end of file diff --git a/pkg/echovault/api_acl.go b/echovault/api_acl.go similarity index 87% rename from pkg/echovault/api_acl.go rename to echovault/api_acl.go index 469609da..61f98f5a 100644 --- a/pkg/echovault/api_acl.go +++ b/echovault/api_acl.go @@ -21,16 +21,16 @@ import ( "github.com/tidwall/resp" ) -// ACLLOADOptions modifies the behaviour of the ACL_LOAD function. +// ACLLoadOptions modifies the behaviour of the ACLLoad function. // If Merge is true, the ACL configuration from the file will be merged with the in-memory ACL configuration. // If Replace is set to true, the ACL configuration from the file will replace the in-memory ACL configuration. // If both flags are set to true, Merge will be prioritised. -type ACLLOADOptions struct { +type ACLLoadOptions struct { Merge bool Replace bool } -// User is the user object passed to the ACL_SETUSER function to update an existing user or create a new user. +// User is the user object passed to the ACLSetUser function to update an existing user or create a new user. // // Username - string - the user's username. // @@ -75,10 +75,10 @@ type ACLLOADOptions struct { // IncludeWriteKeys - []string - the list of keys the user is allowed write access to. The default is all. // This field accepts glob pattern strings. // -// IncludeChannels - []string - the list of PubSub channels the user is allowed to access ("SUBSCRIBE" and "PUBLISH"). +// IncludeChannels - []string - the list of PubSub channels the user is allowed to access ("Subscribe" and "Publish"). // This field accepts glob pattern strings. // -// ExcludeChannels - []string - the list of PubSub channels the user cannot access ("SUBSCRIBE" and "PUBLISH"). +// ExcludeChannels - []string - the list of PubSub channels the user cannot access ("Subscribe" and "Publish"). // This field accepts glob pattern strings. type User struct { Username string @@ -109,7 +109,7 @@ type User struct { ExcludeChannels []string } -// ACL_CAT returns either the list of all categories or the list of commands within a specified category. +// ACLCat returns either the list of all categories or the list of commands within a specified category. // // Parameters: // @@ -122,7 +122,7 @@ type User struct { // Errors: // // "category not found" - when the provided category is not found in the loaded commands. -func (server *EchoVault) ACL_CAT(category ...string) ([]string, error) { +func (server *EchoVault) ACLCat(category ...string) ([]string, error) { cmd := []string{"ACL", "CAT"} if len(category) > 0 { cmd = append(cmd, category[0]) @@ -134,8 +134,8 @@ func (server *EchoVault) ACL_CAT(category ...string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// ACL_USERS returns a string slice containing the usernames of all the loaded users in the ACL module. -func (server *EchoVault) ACL_USERS() ([]string, error) { +// ACLUsers returns a string slice containing the usernames of all the loaded users in the ACL module. +func (server *EchoVault) ACLUsers() ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"ACL", "USERS"}), nil, false, true) if err != nil { return nil, err @@ -143,7 +143,7 @@ func (server *EchoVault) ACL_USERS() ([]string, error) { return internal.ParseStringArrayResponse(b) } -// ACL_SETUSER modifies or creates a new user. If the user with the specified username exists, the ACL user will be modified. +// ACLSetUser modifies or creates a new user. If the user with the specified username exists, the ACL user will be modified. // Otherwise, a new User is created. // // Parameters: @@ -151,7 +151,7 @@ func (server *EchoVault) ACL_USERS() ([]string, error) { // `user` - User - The user object to add/update. // // Returns: "OK" if the user is successfully created/updated. -func (server *EchoVault) ACL_SETUSER(user User) (string, error) { +func (server *EchoVault) ACLSetUser(user User) (string, error) { cmd := []string{"ACL", "SETUSER", user.Username} if user.Enabled { @@ -244,7 +244,7 @@ func (server *EchoVault) ACL_SETUSER(user User) (string, error) { return internal.ParseStringResponse(b) } -// ACL_GETUSER gets the ACL configuration of the name with the given username. +// ACLGetUser gets the ACL configuration of the name with the given username. // // Parameters: // @@ -288,7 +288,7 @@ func (server *EchoVault) ACL_SETUSER(user User) (string, error) { // Errors: // // "user not found" - if the user requested does not exist in the ACL rules. -func (server *EchoVault) ACL_GETUSER(username string) (map[string][]string, error) { +func (server *EchoVault) ACLGetUser(username string) (map[string][]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"ACL", "GETUSER", username}), nil, false, true) if err != nil { return nil, err @@ -317,14 +317,14 @@ func (server *EchoVault) ACL_GETUSER(username string) (map[string][]string, erro return result, nil } -// ACL_DELUSER deletes all the users with the specified usernames. +// ACLDelUser deletes all the users with the specified usernames. // // Parameters: // // `usernames` - ...string - A string of usernames to delete from the ACL module. // // Returns: "OK" if the deletion is successful. -func (server *EchoVault) ACL_DELUSER(usernames ...string) (string, error) { +func (server *EchoVault) ACLDelUser(usernames ...string) (string, error) { cmd := append([]string{"ACL", "DELUSER"}, usernames...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -333,8 +333,8 @@ func (server *EchoVault) ACL_DELUSER(usernames ...string) (string, error) { return internal.ParseStringResponse(b) } -// ACL_LIST lists all the currently loaded ACL users and their rules. -func (server *EchoVault) ACL_LIST() ([]string, error) { +// ACLList lists all the currently loaded ACL users and their rules. +func (server *EchoVault) ACLList() ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"ACL", "LIST"}), nil, false, true) if err != nil { return nil, err @@ -342,15 +342,15 @@ func (server *EchoVault) ACL_LIST() ([]string, error) { return internal.ParseStringArrayResponse(b) } -// ACL_LOAD loads the ACL configuration from the configured ACL file. The load function can either merge the loaded +// ACLLoad loads the ACL configuration from the configured ACL file. The load function can either merge the loaded // config with the in-memory config, or replace the in-memory config with the loaded config entirely. // // Parameters: // -// `options` - ACLLOADOptions - modifies the load behaviour. +// `options` - ACLLoadOptions - modifies the load behaviour. // // Returns: "OK" if the load is successful. -func (server *EchoVault) ACL_LOAD(options ACLLOADOptions) (string, error) { +func (server *EchoVault) ACLLoad(options ACLLoadOptions) (string, error) { cmd := []string{"ACL", "LOAD"} switch { case options.Merge: @@ -369,10 +369,10 @@ func (server *EchoVault) ACL_LOAD(options ACLLOADOptions) (string, error) { return internal.ParseStringResponse(b) } -// ACL_SAVE saves the current ACL configuration to the configured ACL file. +// ACLSave saves the current ACL configuration to the configured ACL file. // // Returns: "OK" if the save is successful. -func (server *EchoVault) ACL_SAVE() (string, error) { +func (server *EchoVault) ACLSave() (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"ACL", "SAVE"}), nil, false, true) if err != nil { return "", err diff --git a/echovault/api_admin.go b/echovault/api_admin.go new file mode 100644 index 00000000..2b815b9a --- /dev/null +++ b/echovault/api_admin.go @@ -0,0 +1,362 @@ +// Copyright 2024 Kelvin Clement Mwinuka +// +// Licensed under the Apache License, Version 2.0 (the "License");s +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package echovault + +import ( + "fmt" + "github.com/echovault/echovault/internal" + "github.com/echovault/echovault/types" + "slices" + "strings" +) + +// CommandListOptions modifies the result from the CommandList command. +// +// ACLCAT filters the results by the provided category. Has the highest priority. +// +// PATTERN filters the result that match the given glob pattern. Has the second-highest priority. +// +// MODULE filters the result by the provided module. Has the lowest priority. +type CommandListOptions struct { + ACLCAT string + PATTERN string + MODULE string +} + +// CommandOptions provides the specification of the command to be added to the EchoVault instance. +// +// Command is the keyword used to trigger this command (e.g. LPUSH, ZADD, ACL ...). +// +// Module is a string that classifies a group of commands. +// +// Categories is a string slice of all the categories that this command belongs to. +// +// Description is a string describing the command, can include an example of how to trigger the command. +// +// SubCommand is a slice of subcommands for this command. +// +// Sync is a boolean value that determines whether this command should be synced across a replication cluster. +// If subcommands are specified, each subcommand will override this value for its own execution. +// +// KeyExtractionFunc is a function that extracts the keys from the command if the command accesses any keys. +// the extracted keys are used by the ACL layer to determine whether a TCP client is authorized to execute this command. +// If subcommands are specified, this function is discarded and each subcommands must implement its own KeyExtractionFunc. +// +// HandlerFunc is the command handler. This function must return a valid RESP2 response as it the command will be +// available to RESP clients. If subcommands are specified, this function is discarded and each subcommand must implement +// its own HandlerFunc. +type CommandOptions struct { + Command string + Module string + Categories []string + Description string + SubCommand []SubCommandOptions + Sync bool + KeyExtractionFunc types.CommandKeyExtractionFunc + HandlerFunc types.CommandHandlerFunc +} + +// SubCommandOptions provides the specification of a subcommand within CommandOptions. +// +// Command is the keyword used to trigger this subcommand (e.g. "CAT" for the subcommand "ACL CAT"). +// +// Module is a string that classifies a group of commands/subcommands. +// +// Categories is a string slice of all the categories that this subcommand belongs to. +// +// Description is a string describing the subcommand, can include an example of how to trigger the subcommand. +// +// Sync is a boolean value that determines whether this subcommand should be synced across a replication cluster. +// This value overrides the Sync value set by the parent command. It's possible to have some synced and un-synced +// subcommands with the same parent command regardless of the parent's Sync value. +// +// KeyExtractionFunc is a function that extracts the keys from the subcommand if it accesses any keys. +// +// HandlerFunc is the subcommand handler. This function must return a valid RESP2 response as it will be +// available to RESP clients. +type SubCommandOptions struct { + Command string + Module string + Categories []string + Description string + Sync bool + KeyExtractionFunc types.CommandKeyExtractionFunc + HandlerFunc types.CommandHandlerFunc +} + +// CommandList returns the list of commands currently loaded in the EchoVault instance. +// +// Parameters: +// +// `options` - CommandListOptions. +// +// Returns: a string slice of all the loaded commands. SubCommands are represented as "command|subcommand". +func (server *EchoVault) CommandList(options CommandListOptions) ([]string, error) { + cmd := []string{"COMMAND", "LIST"} + + switch { + case options.ACLCAT != "": + cmd = append(cmd, []string{"FILTERBY", "ACLCAT", options.ACLCAT}...) + case options.PATTERN != "": + cmd = append(cmd, []string{"FILTERBY", "PATTERN", options.PATTERN}...) + case options.MODULE != "": + cmd = append(cmd, []string{"FILTERBY", "MODULE", options.MODULE}...) + } + + b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) + if err != nil { + return nil, err + } + + return internal.ParseStringArrayResponse(b) +} + +// CommandCount returns the number of commands currently loaded in the EchoVault instance. +// +// Returns: integer representing the count of all available commands. +func (server *EchoVault) CommandCount() (int, error) { + b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"COMMAND", "COUNT"}), nil, false, true) + if err != nil { + return 0, err + } + return internal.ParseIntegerResponse(b) +} + +// Save triggers a new snapshot. +func (server *EchoVault) Save() (string, error) { + b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SAVE"}), nil, false, true) + if err != nil { + return "", err + } + return internal.ParseStringResponse(b) +} + +// LastSave returns the unix epoch milliseconds timestamp of the last save. +func (server *EchoVault) LastSave() (int, error) { + b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LASTSAVE"}), nil, false, true) + if err != nil { + return 0, err + } + return internal.ParseIntegerResponse(b) +} + +// RewriteAOF triggers a compaction of the AOF file. +func (server *EchoVault) RewriteAOF() (string, error) { + b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"REWRITEAOF"}), nil, false, true) + if err != nil { + return "", err + } + return internal.ParseStringResponse(b) +} + +// AddCommand adds a new command to EchoVault. The added command can be executed using the ExecuteCommand method. +// +// Parameters: +// +// `command` - CommandOptions. +// +// Errors: +// +// "command already exists" - If a command with the same command name as the passed command already exists. +func (server *EchoVault) AddCommand(command CommandOptions) error { + // Check if command already exists + for _, c := range server.commands { + if strings.EqualFold(c.Command, command.Command) { + return fmt.Errorf("command %s already exists", command.Command) + } + } + + if command.SubCommand == nil || len(command.SubCommand) == 0 { + // Add command with no subcommands + server.commands = append(server.commands, internal.Command{ + Command: command.Command, + Module: strings.ToLower(command.Module), // Convert module to lower case for uniformity + Categories: func() []string { + // Convert all the categories to lower case for uniformity + cats := make([]string, len(command.Categories)) + for i, cat := range command.Categories { + cats[i] = strings.ToLower(cat) + } + return cats + }(), + Description: command.Description, + Sync: command.Sync, + KeyExtractionFunc: internal.KeyExtractionFunc(func(cmd []string) (internal.KeyExtractionFuncResult, error) { + accessKeys, err := command.KeyExtractionFunc(cmd) + if err != nil { + return internal.KeyExtractionFuncResult{}, err + } + return internal.KeyExtractionFuncResult{ + Channels: []string{}, + ReadKeys: accessKeys.ReadKeys, + WriteKeys: accessKeys.WriteKeys, + }, nil + }), + HandlerFunc: internal.HandlerFunc(func(params internal.HandlerFuncParams) ([]byte, error) { + return command.HandlerFunc(types.CommandHandlerFuncParams{ + Context: params.Context, + Command: params.Command, + Connection: params.Connection, + KeyLock: params.KeyLock, + KeyUnlock: params.KeyUnlock, + KeyRLock: params.KeyRLock, + KeyRUnlock: params.KeyRUnlock, + KeyExists: params.KeyExists, + CreateKeyAndLock: params.CreateKeyAndLock, + GetValue: params.GetValue, + SetValue: params.SetValue, + }) + }), + }) + return nil + } + + // Add command with subcommands + newCommand := internal.Command{ + Command: command.Command, + Module: command.Module, + Categories: func() []string { + // Convert all the categories to lower case for uniformity + cats := make([]string, len(command.Categories)) + for j, cat := range command.Categories { + cats[j] = strings.ToLower(cat) + } + return cats + }(), + Description: command.Description, + Sync: command.Sync, + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{}, nil + }, + HandlerFunc: func(param internal.HandlerFuncParams) ([]byte, error) { return nil, nil }, + SubCommands: make([]internal.SubCommand, len(command.SubCommand)), + } + + for i, sc := range command.SubCommand { + // Skip the subcommand if it already exists in newCommand + if slices.ContainsFunc(newCommand.SubCommands, func(subcommand internal.SubCommand) bool { + return strings.EqualFold(subcommand.Command, sc.Command) + }) { + continue + } + newCommand.SubCommands[i] = internal.SubCommand{ + Command: sc.Command, + Module: strings.ToLower(command.Module), + Categories: func() []string { + // Convert all the categories to lower case for uniformity + cats := make([]string, len(sc.Categories)) + for j, cat := range sc.Categories { + cats[j] = strings.ToLower(cat) + } + return cats + }(), + Description: sc.Description, + Sync: sc.Sync, + KeyExtractionFunc: internal.KeyExtractionFunc(func(cmd []string) (internal.KeyExtractionFuncResult, error) { + accessKeys, err := sc.KeyExtractionFunc(cmd) + if err != nil { + return internal.KeyExtractionFuncResult{}, err + } + return internal.KeyExtractionFuncResult{ + Channels: []string{}, + ReadKeys: accessKeys.ReadKeys, + WriteKeys: accessKeys.WriteKeys, + }, nil + }), + HandlerFunc: internal.HandlerFunc(func(params internal.HandlerFuncParams) ([]byte, error) { + return sc.HandlerFunc(types.CommandHandlerFuncParams{ + Context: params.Context, + Command: params.Command, + Connection: params.Connection, + KeyLock: params.KeyLock, + KeyUnlock: params.KeyUnlock, + KeyRLock: params.KeyRLock, + KeyRUnlock: params.KeyRUnlock, + KeyExists: params.KeyExists, + CreateKeyAndLock: params.CreateKeyAndLock, + GetValue: params.GetValue, + SetValue: params.SetValue, + }) + }), + } + } + + server.commands = append(server.commands, newCommand) + + return nil +} + +// ExecuteCommand executes the command passed to it. If 1 string is passed, EchoVault will try to +// execute the command. If 2 strings are passed, EchoVault will attempt to execute the subcommand of the command. +// If more than 2 strings are provided, all additional strings will be ignored. +// +// This method returns the raw RESP response from the command handler. You will have to parse the RESP response if +// you want to use the return value from the handler. +// +// This method does not work with handlers that manipulate the client connection directly (i.e SUBSCRIBE, PSUBSCRIBE). +// If you'd like to (p)subscribe or (p)unsubscribe, use the (P)SUBSCRIBE and (P)UNSUBSCRIBE methods instead. +// +// Parameters: +// +// `command` - ...string. +// +// Returns: []byte - Raw RESP response returned by the command handler. +// +// Errors: +// +// All errors from the command handler are forwarded to the caller. Other errors returned include: +// +// "command not supported" - If the command does not exist. +// +// "command not supported" - If the command exists but the subcommand does not exist for that command. +func (server *EchoVault) ExecuteCommand(command ...string) ([]byte, error) { + return server.handleCommand(server.context, internal.EncodeCommand(command), nil, false, true) +} + +// RemoveCommand removes the specified command or subcommand from EchoVault. +// When commands are removed, they will no longer be available for both the embedded instance and for TCP clients. +// +// Note: If a command is removed, the API wrapper for the command will also be unusable. +// For example, calling RemoveCommand("LPUSH") will cause the LPUSH method to always return a +// "command LPUSH not supported" error so use this method with caution. +// +// If one string is passed, the command matching that string is removed along will all of its subcommand if it has any. +// If two strings are passed, only the subcommand of the specified command is removed. +// If more than 2 strings are passed, all additional strings are ignored. +// +// Parameters: +// +// `command` - ...string. +func (server *EchoVault) RemoveCommand(command ...string) { + switch len(command) { + case 1: + // Remove command + server.commands = slices.DeleteFunc(server.commands, func(c internal.Command) bool { + return strings.EqualFold(c.Command, command[0]) + }) + case 2: + // Remove subcommand + for i := 0; i < len(server.commands); i++ { + if !strings.EqualFold(server.commands[i].Command, command[0]) { + continue + } + if server.commands[i].SubCommands != nil && len(server.commands[i].SubCommands) > 0 { + server.commands[i].SubCommands = slices.DeleteFunc(server.commands[i].SubCommands, func(sc internal.SubCommand) bool { + return strings.EqualFold(sc.Command, command[1]) + }) + } + } + } +} diff --git a/pkg/echovault/api_connection.go b/echovault/api_connection.go similarity index 100% rename from pkg/echovault/api_connection.go rename to echovault/api_connection.go diff --git a/pkg/echovault/api_generic.go b/echovault/api_generic.go similarity index 81% rename from pkg/echovault/api_generic.go rename to echovault/api_generic.go index 86a6e9bb..781ec06f 100644 --- a/pkg/echovault/api_generic.go +++ b/echovault/api_generic.go @@ -19,7 +19,7 @@ import ( "strconv" ) -// SETOptions modifies the behaviour for the SET command +// SetOptions modifies the behaviour for the Set command // // NX - Only set if the key does not exist. NX is higher priority than XX. // @@ -38,7 +38,7 @@ import ( // // PXAT - Expire at the exat time in unix milliseconds (positive integer). // PXAT has the least priority. -type SETOptions struct { +type SetOptions struct { NX bool XX bool GET bool @@ -48,7 +48,7 @@ type SETOptions struct { PXAT int } -// EXPIREOptions modifies the behaviour of the EXPIRE, PEXPIRE, EXPIREAT, PEXPIREAT. +// ExpireOptions modifies the behaviour of the Expire, PExpire, ExpireAt, PExpireAt. // // NX - Only set the expiry time if the key has no associated expiry. // @@ -57,17 +57,17 @@ type SETOptions struct { // GT - Only set the expiry time if the new expiry time is greater than the current one. // // LT - Only set the expiry time if the new expiry time is less than the current one. -type EXPIREOptions struct { +type ExpireOptions struct { NX bool XX bool LT bool GT bool } -type PEXPIREOptions EXPIREOptions -type EXPIREATOptions EXPIREOptions -type PEXPIREATOptions EXPIREOptions +type PExpireOptions ExpireOptions +type ExpireAtOptions ExpireOptions +type PExpireAtOptions ExpireOptions -// SET creates or modifies the value at the given key. +// Set creates or modifies the value at the given key. // // Parameters: // @@ -75,16 +75,16 @@ type PEXPIREATOptions EXPIREOptions // // `value` - string - the value to place at the key. // -// `options` - SETOptions. +// `options` - SetOptions. // -// Returns: "OK" if the set is successful, If the "GET" flag in SETOptions is set to true, the previous value is returned. +// Returns: "OK" if the set is successful, If the "Get" flag in SetOptions is set to true, the previous value is returned. // // Errors: // // "key does not exist"" - when the XX flag is set to true and the key does not exist. // // "key does already exists" - when the NX flag is set to true and the key already exists. -func (server *EchoVault) SET(key, value string, options SETOptions) (string, error) { +func (server *EchoVault) Set(key, value string, options SetOptions) (string, error) { cmd := []string{"SET", key, value} switch { @@ -117,7 +117,7 @@ func (server *EchoVault) SET(key, value string, options SETOptions) (string, err return internal.ParseStringResponse(b) } -// MSET set multiple values at multiple keys with one command. Existing keys are overwritten and non-existent +// MSet set multiple values at multiple keys with one command. Existing keys are overwritten and non-existent // keys are created. // // Parameters: @@ -129,7 +129,7 @@ func (server *EchoVault) SET(key, value string, options SETOptions) (string, err // Errors: // // "key does already exists" - when the NX flag is set to true and the key already exists. -func (server *EchoVault) MSET(kvPairs map[string]string) (string, error) { +func (server *EchoVault) MSet(kvPairs map[string]string) (string, error) { cmd := []string{"MSET"} for k, v := range kvPairs { @@ -144,7 +144,7 @@ func (server *EchoVault) MSET(kvPairs map[string]string) (string, error) { return internal.ParseStringResponse(b) } -// GET retrieves the value at the provided key. +// Get retrieves the value at the provided key. // // Parameters: // @@ -152,7 +152,7 @@ func (server *EchoVault) MSET(kvPairs map[string]string) (string, error) { // // Returns: A string representing the value at the specified key. If the value does not exist, an empty // string is returned. -func (server *EchoVault) GET(key string) (string, error) { +func (server *EchoVault) Get(key string) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"GET", key}), nil, false, true) if err != nil { return "", err @@ -160,7 +160,7 @@ func (server *EchoVault) GET(key string) (string, error) { return internal.ParseStringResponse(b) } -// MGET get multiple values from the list of provided keys. The index of each value corresponds to the index of its key +// MGet get multiple values from the list of provided keys. The index of each value corresponds to the index of its key // in the parameter slice. Values that do not exist will be an empty string. // // Parameters: @@ -168,7 +168,7 @@ func (server *EchoVault) GET(key string) (string, error) { // `keys` - []string - a string slice of all the keys. // // Returns: a string slice of all the values. -func (server *EchoVault) MGET(keys ...string) ([]string, error) { +func (server *EchoVault) MGet(keys ...string) ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand(append([]string{"MGET"}, keys...)), nil, false, true) if err != nil { return []string{}, err @@ -176,14 +176,14 @@ func (server *EchoVault) MGET(keys ...string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// DEL removes the given keys from the store. +// Del removes the given keys from the store. // // Parameters: // // `keys` - []string - the keys to delete from the store. // // Returns: The number of keys that were successfully deleted. -func (server *EchoVault) DEL(keys ...string) (int, error) { +func (server *EchoVault) Del(keys ...string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand(append([]string{"DEL"}, keys...)), nil, false, true) if err != nil { return 0, err @@ -191,7 +191,7 @@ func (server *EchoVault) DEL(keys ...string) (int, error) { return internal.ParseIntegerResponse(b) } -// PERSIST removes the expiry associated with a key and makes it permanent. +// Persist removes the expiry associated with a key and makes it permanent. // Has no effect on a key that is already persistent. // // Parameters: @@ -199,7 +199,7 @@ func (server *EchoVault) DEL(keys ...string) (int, error) { // `key` - string - the key to persist. // // Returns: true if the keys is successfully persisted. -func (server *EchoVault) PERSIST(key string) (bool, error) { +func (server *EchoVault) Persist(key string) (bool, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"PERSIST", key}), nil, false, true) if err != nil { return false, err @@ -207,14 +207,14 @@ func (server *EchoVault) PERSIST(key string) (bool, error) { return internal.ParseBooleanResponse(b) } -// EXPIRETIME return the current key's expiry time in unix epoch seconds. +// ExpireTime return the current key's expiry time in unix epoch seconds. // // Parameters: // // `key` - string. // // Returns: -2 if the keys does not exist, -1 if the key exists but has no expiry time, seconds if the key has an expiry. -func (server *EchoVault) EXPIRETIME(key string) (int, error) { +func (server *EchoVault) ExpireTime(key string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"EXPIRETIME", key}), nil, false, true) if err != nil { return 0, err @@ -222,14 +222,14 @@ func (server *EchoVault) EXPIRETIME(key string) (int, error) { return internal.ParseIntegerResponse(b) } -// PEXPIRETIME return the current key's expiry time in unix epoch milliseconds. +// PExpireTime return the current key's expiry time in unix epoch milliseconds. // // Parameters: // // `key` - string. // // Returns: -2 if the keys does not exist, -1 if the key exists but has no expiry time, seconds if the key has an expiry. -func (server *EchoVault) PEXPIRETIME(key string) (int, error) { +func (server *EchoVault) PExpireTime(key string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"PEXPIRETIME", key}), nil, false, true) if err != nil { return 0, err @@ -267,7 +267,7 @@ func (server *EchoVault) PTTL(key string) (int, error) { return internal.ParseIntegerResponse(b) } -// EXPIRE set the given key's expiry in seconds from now. +// Expire set the given key's expiry in seconds from now. // This command turns a persistent key into a volatile one. // // Parameters: @@ -276,10 +276,10 @@ func (server *EchoVault) PTTL(key string) (int, error) { // // `seconds` - int - number of seconds from now. // -// `options` - EXPIREOptions +// `options` - ExpireOptions // // Returns: true if the key's expiry was successfully updated. -func (server *EchoVault) EXPIRE(key string, seconds int, options EXPIREOptions) (int, error) { +func (server *EchoVault) Expire(key string, seconds int, options ExpireOptions) (int, error) { cmd := []string{"EXPIRE", key, strconv.Itoa(seconds)} switch { @@ -301,7 +301,7 @@ func (server *EchoVault) EXPIRE(key string, seconds int, options EXPIREOptions) return internal.ParseIntegerResponse(b) } -// PEXPIRE set the given key's expiry in milliseconds from now. +// PExpire set the given key's expiry in milliseconds from now. // This command turns a persistent key into a volatile one. // // Parameters: @@ -310,10 +310,10 @@ func (server *EchoVault) EXPIRE(key string, seconds int, options EXPIREOptions) // // `milliseconds` - int - number of seconds from now. // -// `options` - PEXPIREOptions +// `options` - PExpireOptions // // Returns: true if the key's expiry was successfully updated. -func (server *EchoVault) PEXPIRE(key string, milliseconds int, options PEXPIREOptions) (int, error) { +func (server *EchoVault) PExpire(key string, milliseconds int, options PExpireOptions) (int, error) { cmd := []string{"PEXPIRE", key, strconv.Itoa(milliseconds)} switch { @@ -335,7 +335,7 @@ func (server *EchoVault) PEXPIRE(key string, milliseconds int, options PEXPIREOp return internal.ParseIntegerResponse(b) } -// EXPIREAT set the given key's expiry in unix epoch seconds. +// ExpireAt set the given key's expiry in unix epoch seconds. // This command turns a persistent key into a volatile one. // // Parameters: @@ -344,10 +344,10 @@ func (server *EchoVault) PEXPIRE(key string, milliseconds int, options PEXPIREOp // // `unixSeconds` - int - number of seconds from now. // -// `options` - EXPIREATOptions +// `options` - ExpireAtOptions // // Returns: true if the key's expiry was successfully updated. -func (server *EchoVault) EXPIREAT(key string, unixSeconds int, options EXPIREATOptions) (int, error) { +func (server *EchoVault) ExpireAt(key string, unixSeconds int, options ExpireAtOptions) (int, error) { cmd := []string{"EXPIREAT", key, strconv.Itoa(unixSeconds)} switch { @@ -369,7 +369,7 @@ func (server *EchoVault) EXPIREAT(key string, unixSeconds int, options EXPIREATO return internal.ParseIntegerResponse(b) } -// PEXPIREAT set the given key's expiry in unix epoch milliseconds. +// PExpireAt set the given key's expiry in unix epoch milliseconds. // This command turns a persistent key into a volatile one. // // Parameters: @@ -378,10 +378,10 @@ func (server *EchoVault) EXPIREAT(key string, unixSeconds int, options EXPIREATO // // `unixMilliseconds` - int - number of seconds from now. // -// `options` - PEXPIREATOptions +// `options` - PExpireAtOptions // // Returns: true if the key's expiry was successfully updated. -func (server *EchoVault) PEXPIREAT(key string, unixMilliseconds int, options PEXPIREATOptions) (int, error) { +func (server *EchoVault) PExpireAt(key string, unixMilliseconds int, options PExpireAtOptions) (int, error) { cmd := []string{"PEXPIREAT", key, strconv.Itoa(unixMilliseconds)} switch { diff --git a/pkg/echovault/api_hash.go b/echovault/api_hash.go similarity index 83% rename from pkg/echovault/api_hash.go rename to echovault/api_hash.go index 616ee1fd..8e53d56d 100644 --- a/pkg/echovault/api_hash.go +++ b/echovault/api_hash.go @@ -19,17 +19,17 @@ import ( "strconv" ) -// HRANDFIELDOptions modifies the behaviour of the HRANDFIELD function. +// HRandFieldOptions modifies the behaviour of the HRandField function. // // Count determines the number of random fields to return. If set to 0, an empty slice will be returned. // // WithValues determines whether the returned map should contain the values as well as the fields. -type HRANDFIELDOptions struct { +type HRandFieldOptions struct { Count uint WithValues bool } -// HSET creates or modifies a hash map with the values provided. If the hash map does not exist it will be created. +// HSet creates or modifies a hash map with the values provided. If the hash map does not exist it will be created. // // Parameters: // @@ -43,7 +43,7 @@ type HRANDFIELDOptions struct { // Errors: // // "value at is not a hash" - when the provided key exists but is not a hash. -func (server *EchoVault) HSET(key string, fieldValuePairs map[string]string) (int, error) { +func (server *EchoVault) HSet(key string, fieldValuePairs map[string]string) (int, error) { cmd := []string{"HSET", key} for k, v := range fieldValuePairs { @@ -58,7 +58,7 @@ func (server *EchoVault) HSET(key string, fieldValuePairs map[string]string) (in return internal.ParseIntegerResponse(b) } -// HSETNX modifies an existing hash map with the values provided. This function will only be successful if the +// HSetNX modifies an existing hash map with the values provided. This function will only be successful if the // hash map already exists. // // Parameters: @@ -73,7 +73,7 @@ func (server *EchoVault) HSET(key string, fieldValuePairs map[string]string) (in // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HSETNX(key string, fieldValuePairs map[string]string) (int, error) { +func (server *EchoVault) HSetNX(key string, fieldValuePairs map[string]string) (int, error) { cmd := []string{"HSETNX", key} for k, v := range fieldValuePairs { @@ -88,7 +88,7 @@ func (server *EchoVault) HSETNX(key string, fieldValuePairs map[string]string) ( return internal.ParseIntegerResponse(b) } -// HSTRLEN returns the length of the values held at the specified fields of a hash map. +// HStrLen returns the length of the values held at the specified fields of a hash map. // // Parameters: // @@ -102,7 +102,7 @@ func (server *EchoVault) HSETNX(key string, fieldValuePairs map[string]string) ( // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HSTRLEN(key string, fields ...string) ([]int, error) { +func (server *EchoVault) HStrLen(key string, fields ...string) ([]int, error) { cmd := append([]string{"HSTRLEN", key}, fields...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) @@ -113,7 +113,7 @@ func (server *EchoVault) HSTRLEN(key string, fields ...string) ([]int, error) { return internal.ParseIntegerArrayResponse(b) } -// HVALS returns all the values in a hash map. +// HVals returns all the values in a hash map. // // Parameters: // @@ -124,7 +124,7 @@ func (server *EchoVault) HSTRLEN(key string, fields ...string) ([]int, error) { // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HVALS(key string) ([]string, error) { +func (server *EchoVault) HVals(key string) ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"HVALS", key}), nil, false, true) if err != nil { return nil, err @@ -132,20 +132,20 @@ func (server *EchoVault) HVALS(key string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// HRANDFIELD returns a random list of fields from the hash map. +// HRandField returns a random list of fields from the hash map. // // Parameters: // // `key` - string - the key to the hash map. // -// `options` - HRANDFIELDOptions +// `options` - HRandFieldOptions // // Returns: a string slice containing random fields of the hash map. If the key does not exist, an empty slice is returned. // // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HRANDFIELD(key string, options HRANDFIELDOptions) ([]string, error) { +func (server *EchoVault) HRandField(key string, options HRandFieldOptions) ([]string, error) { cmd := []string{"HRANDFIELD", key} if options.Count == 0 { @@ -166,7 +166,7 @@ func (server *EchoVault) HRANDFIELD(key string, options HRANDFIELDOptions) ([]st return internal.ParseStringArrayResponse(b) } -// HLEN returns the length of the hash map. +// HLen returns the length of the hash map. // // Parameters: // @@ -177,7 +177,7 @@ func (server *EchoVault) HRANDFIELD(key string, options HRANDFIELDOptions) ([]st // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HLEN(key string) (int, error) { +func (server *EchoVault) HLen(key string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"HLEN", key}), nil, false, true) if err != nil { return 0, err @@ -185,7 +185,7 @@ func (server *EchoVault) HLEN(key string) (int, error) { return internal.ParseIntegerResponse(b) } -// HKEYS returns all the keys in a hash map. +// HKeys returns all the keys in a hash map. // // Parameters: // @@ -196,7 +196,7 @@ func (server *EchoVault) HLEN(key string) (int, error) { // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HKEYS(key string) ([]string, error) { +func (server *EchoVault) HKeys(key string) ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"HKEYS", key}), nil, false, true) if err != nil { return nil, err @@ -204,7 +204,7 @@ func (server *EchoVault) HKEYS(key string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// HINCRBY increment the value of the hash map at the given field by an integer. If the hash map does not exist, +// HIncrBy increment the value of the hash map at the given field by an integer. If the hash map does not exist, // a new hash map is created with the field and increment as the value. // // Parameters: @@ -220,7 +220,7 @@ func (server *EchoVault) HKEYS(key string) ([]string, error) { // "value at is not a hash" - when the provided key does not exist or is not a hash. // // "value at field is not a number" - when the field holds a value that is not a number. -func (server *EchoVault) HINCRBY(key, field string, increment int) (float64, error) { +func (server *EchoVault) HIncrBy(key, field string, increment int) (float64, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"HINCRBY", key, field, strconv.Itoa(increment)}), nil, false, true) if err != nil { return 0, err @@ -228,8 +228,8 @@ func (server *EchoVault) HINCRBY(key, field string, increment int) (float64, err return internal.ParseFloatResponse(b) } -// HINCRBYFLOAT behaves like HINCRBY but with a float increment instead of an integer increment. -func (server *EchoVault) HINCRBYFLOAT(key, field string, increment float64) (float64, error) { +// HIncrByFloat behaves like HIncrBy but with a float increment instead of an integer increment. +func (server *EchoVault) HIncrByFloat(key, field string, increment float64) (float64, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"HINCRBYFLOAT", key, field, strconv.FormatFloat(increment, 'f', -1, 64)}), nil, false, true) if err != nil { return 0, err @@ -237,7 +237,7 @@ func (server *EchoVault) HINCRBYFLOAT(key, field string, increment float64) (flo return internal.ParseFloatResponse(b) } -// HGETALL returns a flattened slice of all keys and values in a hash map. +// HGetAll returns a flattened slice of all keys and values in a hash map. // // Parameters: // @@ -249,7 +249,7 @@ func (server *EchoVault) HINCRBYFLOAT(key, field string, increment float64) (flo // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HGETALL(key string) ([]string, error) { +func (server *EchoVault) HGetAll(key string) ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"HGETALL", key}), nil, false, true) if err != nil { return nil, err @@ -257,7 +257,7 @@ func (server *EchoVault) HGETALL(key string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// HEXISTS checks if a field exists in a hash map. +// HExists checks if a field exists in a hash map. // // Parameters: // @@ -270,7 +270,7 @@ func (server *EchoVault) HGETALL(key string) ([]string, error) { // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HEXISTS(key, field string) (bool, error) { +func (server *EchoVault) HExists(key, field string) (bool, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"HEXISTS", key, field}), nil, false, true) if err != nil { return false, err @@ -278,7 +278,7 @@ func (server *EchoVault) HEXISTS(key, field string) (bool, error) { return internal.ParseBooleanResponse(b) } -// HDEL delete 1 or more fields from a hash map. +// HDel delete 1 or more fields from a hash map. // // Parameters: // @@ -291,7 +291,7 @@ func (server *EchoVault) HEXISTS(key, field string) (bool, error) { // Errors: // // "value at is not a hash" - when the provided key does not exist or is not a hash. -func (server *EchoVault) HDEL(key string, fields ...string) (int, error) { +func (server *EchoVault) HDel(key string, fields ...string) (int, error) { cmd := append([]string{"HDEL", key}, fields...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { diff --git a/pkg/echovault/api_list.go b/echovault/api_list.go similarity index 72% rename from pkg/echovault/api_list.go rename to echovault/api_list.go index 56963182..0b9f3ad2 100644 --- a/pkg/echovault/api_list.go +++ b/echovault/api_list.go @@ -20,7 +20,7 @@ import ( "strconv" ) -// LLEN returns the length of the list. +// LLen returns the length of the list. // // Parameters: // @@ -30,8 +30,8 @@ import ( // // Errors: // -// "LLEN command on non-list item" - when the provided key exists but is not a list. -func (server *EchoVault) LLEN(key string) (int, error) { +// "LLen command on non-list item" - when the provided key exists but is not a list. +func (server *EchoVault) LLen(key string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LLEN", key}), nil, false, true) fmt.Println(key, string(b), err) if err != nil { @@ -40,7 +40,7 @@ func (server *EchoVault) LLEN(key string) (int, error) { return internal.ParseIntegerResponse(b) } -// LRANGE returns the elements within the index range provided. +// LRange returns the elements within the index range provided. // // Parameters: // @@ -55,12 +55,12 @@ func (server *EchoVault) LLEN(key string) (int, error) { // // Errors: // -// "LRANGE command on non-list item" - when the provided key exists but is not a list. +// "LRange command on non-list item" - when the provided key exists but is not a list. // // "start index must be within list boundary" - when the start index is not within the list boundaries. // // "end index must be within list range or -1" - when end index is not within the list boundaries. -func (server *EchoVault) LRANGE(key string, start, end int) ([]string, error) { +func (server *EchoVault) LRange(key string, start, end int) ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LRANGE", key, strconv.Itoa(start), strconv.Itoa(end)}), nil, false, true) if err != nil { return nil, err @@ -68,7 +68,7 @@ func (server *EchoVault) LRANGE(key string, start, end int) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// LINDEX retrieves the element at the provided index from the list without removing it. +// LIndex retrieves the element at the provided index from the list without removing it. // // Parameters: // @@ -80,10 +80,10 @@ func (server *EchoVault) LRANGE(key string, start, end int) ([]string, error) { // // Errors: // -// "LINDEX command on non-list item" - when the provided key exists but is not a list. +// "LIndex command on non-list item" - when the provided key exists but is not a list. // // "index must be within list range" - when the index is not within the list boundary. -func (server *EchoVault) LINDEX(key string, index uint) (string, error) { +func (server *EchoVault) LIndex(key string, index uint) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LINDEX", key, strconv.Itoa(int(index))}), nil, false, true) if err != nil { return "", err @@ -91,7 +91,7 @@ func (server *EchoVault) LINDEX(key string, index uint) (string, error) { return internal.ParseStringResponse(b) } -// LSET updates the value at the given index of a list. +// LSet updates the value at the given index of a list. // // Parameters: // @@ -105,10 +105,10 @@ func (server *EchoVault) LINDEX(key string, index uint) (string, error) { // // Errors: // -// "LSET command on non-list item" - when the provided key exists but is not a list. +// "LSet command on non-list item" - when the provided key exists but is not a list. // // "index must be within list range" - when the index is not within the list boundary. -func (server *EchoVault) LSET(key string, index int, value string) (string, error) { +func (server *EchoVault) LSet(key string, index int, value string) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LSET", key, strconv.Itoa(index), value}), nil, false, true) if err != nil { return "", err @@ -116,9 +116,9 @@ func (server *EchoVault) LSET(key string, index int, value string) (string, erro return internal.ParseStringResponse(b) } -// LTRIM work similarly to LRANGE but instead of returning the new list, it replaces the original list with the +// LTrim work similarly to LRange but instead of returning the new list, it replaces the original list with the // trimmed list. -func (server *EchoVault) LTRIM(key string, start int, end int) (string, error) { +func (server *EchoVault) LTrim(key string, start int, end int) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LTRIM", key, strconv.Itoa(start), strconv.Itoa(end)}), nil, false, true) if err != nil { return "", err @@ -126,7 +126,7 @@ func (server *EchoVault) LTRIM(key string, start int, end int) (string, error) { return internal.ParseStringResponse(b) } -// LREM removes 'count' instances of the specified element from the list. +// LRem removes 'count' instances of the specified element from the list. // // Parameters: // @@ -140,8 +140,8 @@ func (server *EchoVault) LTRIM(key string, start int, end int) (string, error) { // // Errors: // -// "LREM command on non-list item" - when the provided key exists but is not a list. -func (server *EchoVault) LREM(key string, count int, value string) (string, error) { +// "LRem command on non-list item" - when the provided key exists but is not a list. +func (server *EchoVault) LRem(key string, count int, value string) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LREM", key, strconv.Itoa(count), value}), nil, false, true) if err != nil { return "", err @@ -149,7 +149,7 @@ func (server *EchoVault) LREM(key string, count int, value string) (string, erro return internal.ParseStringResponse(b) } -// LMOVE moves an element from one list to another. +// LMove moves an element from one list to another. // // Parameters: // @@ -170,7 +170,7 @@ func (server *EchoVault) LREM(key string, count int, value string) (string, erro // "both source and destination must be lists" - when either source or destination are not lists. // // "wherefrom and whereto arguments must be either LEFT or RIGHT" - if whereFrom or whereTo are not either "LEFT" or "RIGHT". -func (server *EchoVault) LMOVE(source, destination, whereFrom, whereTo string) (string, error) { +func (server *EchoVault) LMove(source, destination, whereFrom, whereTo string) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LMOVE", source, destination, whereFrom, whereTo}), nil, false, true) if err != nil { return "", err @@ -178,7 +178,7 @@ func (server *EchoVault) LMOVE(source, destination, whereFrom, whereTo string) ( return internal.ParseStringResponse(b) } -// LPOP pops an element from the start of the list and return it. +// LPop pops an element from the start of the list and return it. // // Parameters: // @@ -188,8 +188,8 @@ func (server *EchoVault) LMOVE(source, destination, whereFrom, whereTo string) ( // // Errors: // -// "LPOP command on non-list item" - when the provided key is not a list. -func (server *EchoVault) LPOP(key string) (string, error) { +// "LPop command on non-list item" - when the provided key is not a list. +func (server *EchoVault) LPop(key string) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LPOP", key}), nil, false, true) if err != nil { return "", err @@ -197,7 +197,7 @@ func (server *EchoVault) LPOP(key string) (string, error) { return internal.ParseStringResponse(b) } -// RPOP pops an element from the end of the list and return it. +// RPop pops an element from the end of the list and return it. // // Parameters: // @@ -207,8 +207,8 @@ func (server *EchoVault) LPOP(key string) (string, error) { // // Errors: // -// "RPOP command on non-list item" - when the provided key is not a list. -func (server *EchoVault) RPOP(key string) (string, error) { +// "RPop command on non-list item" - when the provided key is not a list. +func (server *EchoVault) RPop(key string) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"RPOP", key}), nil, false, true) if err != nil { return "", err @@ -216,7 +216,7 @@ func (server *EchoVault) RPOP(key string) (string, error) { return internal.ParseStringResponse(b) } -// LPUSH pushed 1 or more values to the beginning of a list. If the list does not exist, a new list is created +// LPush pushed 1 or more values to the beginning of a list. If the list does not exist, a new list is created // wth the passed elements as its members. // // Parameters: @@ -225,21 +225,21 @@ func (server *EchoVault) RPOP(key string) (string, error) { // // `values` - ...string - the list of elements to add to push to the beginning of the list. // -// Returns: "OK" when the list has been successfully modified or created. +// Returns: An integer with the length of the new list. // // Errors: // -// "LPUSH command on non-list item" - when the provided key is not a list. -func (server *EchoVault) LPUSH(key string, values ...string) (string, error) { +// "LPush command on non-list item" - when the provided key is not a list. +func (server *EchoVault) LPush(key string, values ...string) (int, error) { cmd := append([]string{"LPUSH", key}, values...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { - return "", err + return 0, err } - return internal.ParseStringResponse(b) + return internal.ParseIntegerResponse(b) } -// LPUSHX pushed 1 or more values to the beginning of an existing list. The command only succeeds on a pre-existing list. +// LPushX pushed 1 or more values to the beginning of an existing list. The command only succeeds on a pre-existing list. // // Parameters: // @@ -247,21 +247,21 @@ func (server *EchoVault) LPUSH(key string, values ...string) (string, error) { // // `values` - ...string - the list of elements to add to push to the beginning of the list. // -// Returns: "OK" when the list has been successfully modified. +// Returns: An integer with the length of the new list. // // Errors: // -// "LPUSHX command on non-list item" - when the provided key is not a list or doesn't exist. -func (server *EchoVault) LPUSHX(key string, values ...string) (string, error) { +// "LPushX command on non-list item" - when the provided key is not a list or doesn't exist. +func (server *EchoVault) LPushX(key string, values ...string) (int, error) { cmd := append([]string{"LPUSHX", key}, values...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { - return "", err + return 0, err } - return internal.ParseStringResponse(b) + return internal.ParseIntegerResponse(b) } -// RPUSH pushed 1 or more values to the end of a list. If the list does not exist, a new list is created +// RPush pushed 1 or more values to the end of a list. If the list does not exist, a new list is created // wth the passed elements as its members. // // Parameters: @@ -270,21 +270,21 @@ func (server *EchoVault) LPUSHX(key string, values ...string) (string, error) { // // `values` - ...string - the list of elements to add to push to the end of the list. // -// Returns: "OK" when the list has been successfully modified or created. +// Returns: An integer with the length of the new list. // // Errors: // -// "RPUSH command on non-list item" - when the provided key is not a list. -func (server *EchoVault) RPUSH(key string, values ...string) (string, error) { +// "RPush command on non-list item" - when the provided key is not a list. +func (server *EchoVault) RPush(key string, values ...string) (int, error) { cmd := append([]string{"RPUSH", key}, values...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { - return "", err + return 0, err } - return internal.ParseStringResponse(b) + return internal.ParseIntegerResponse(b) } -// RPUSHX pushed 1 or more values to the end of an existing list. The command only succeeds on a pre-existing list. +// RPushX pushed 1 or more values to the end of an existing list. The command only succeeds on a pre-existing list. // // Parameters: // @@ -292,16 +292,16 @@ func (server *EchoVault) RPUSH(key string, values ...string) (string, error) { // // `values` - ...string - the list of elements to add to push to the end of the list. // -// Returns: "OK" when the list has been successfully modified. +// Returns: An integer with the length of the new list. // // Errors: // -// "RPUSHX command on non-list item" - when the provided key is not a list or doesn't exist. -func (server *EchoVault) RPUSHX(key string, values ...string) (string, error) { +// "RPushX command on non-list item" - when the provided key is not a list or doesn't exist. +func (server *EchoVault) RPushX(key string, values ...string) (int, error) { cmd := append([]string{"RPUSHX", key}, values...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { - return "", err + return 0, err } - return internal.ParseStringResponse(b) + return internal.ParseIntegerResponse(b) } diff --git a/pkg/echovault/api_pubsub.go b/echovault/api_pubsub.go similarity index 85% rename from pkg/echovault/api_pubsub.go rename to echovault/api_pubsub.go index 6690b9c8..be2c745b 100644 --- a/pkg/echovault/api_pubsub.go +++ b/echovault/api_pubsub.go @@ -28,7 +28,7 @@ type conn struct { var connections map[string]conn -// ReadPubSubMessage is returned by the SUBSCRIBE and PSUBSCRIBE functions. +// ReadPubSubMessage is returned by the Subscribe and PSubscribe functions. // // This function is lazy, therefore it needs to be invoked in order to read the next message. // When the message is read, the function returns a string slice with 3 elements. @@ -36,7 +36,7 @@ var connections map[string]conn // Index 2 holds the actual message. type ReadPubSubMessage func() []string -// SUBSCRIBE subscribes the caller to the list of provided channels. +// Subscribe subscribes the caller to the list of provided channels. // // Parameters: // @@ -46,7 +46,7 @@ type ReadPubSubMessage func() []string // // Returns: ReadPubSubMessage function which reads the next message sent to the subscription instance. // This function is blocking. -func (server *EchoVault) SUBSCRIBE(tag string, channels ...string) ReadPubSubMessage { +func (server *EchoVault) Subscribe(tag string, channels ...string) ReadPubSubMessage { // Initialize connection tracker if calling subscribe for the first time if connections == nil { connections = make(map[string]conn) @@ -82,14 +82,14 @@ func (server *EchoVault) SUBSCRIBE(tag string, channels ...string) ReadPubSubMes } } -// UNSUBSCRIBE unsubscribes the caller from the given channels. +// Unsubscribe unsubscribes the caller from the given channels. // // Parameters: // // `tag` - string - The tag used to identify this subscription instance. // // `channels` - ...string - The list of channels to unsubscribe from. -func (server *EchoVault) UNSUBSCRIBE(tag string, channels ...string) { +func (server *EchoVault) Unsubscribe(tag string, channels ...string) { if connections == nil { return } @@ -102,7 +102,7 @@ func (server *EchoVault) UNSUBSCRIBE(tag string, channels ...string) { _, _ = server.handleCommand(server.context, internal.EncodeCommand(cmd), connections[tag].writeConn, false, true) } -// PSUBSCRIBE subscribes the caller to the list of provided glob patterns. +// PSubscribe subscribes the caller to the list of provided glob patterns. // // Parameters: // @@ -112,7 +112,7 @@ func (server *EchoVault) UNSUBSCRIBE(tag string, channels ...string) { // // Returns: ReadPubSubMessage function which reads the next message sent to the subscription instance. // This function is blocking. -func (server *EchoVault) PSUBSCRIBE(tag string, patterns ...string) ReadPubSubMessage { +func (server *EchoVault) PSubscribe(tag string, patterns ...string) ReadPubSubMessage { // Initialize connection tracker if calling subscribe for the first time if connections == nil { connections = make(map[string]conn) @@ -148,14 +148,14 @@ func (server *EchoVault) PSUBSCRIBE(tag string, patterns ...string) ReadPubSubMe } } -// PUNSUBSCRIBE unsubscribes the caller from the given glob patterns. +// PUnsubscribe unsubscribes the caller from the given glob patterns. // // Parameters: // // `tag` - string - The tag used to identify this subscription instance. // // `patterns` - ...string - The list of glob patterns to unsubscribe from. -func (server *EchoVault) PUNSUBSCRIBE(tag string, patterns ...string) { +func (server *EchoVault) PUnsubscribe(tag string, patterns ...string) { if connections == nil { return } @@ -168,7 +168,7 @@ func (server *EchoVault) PUNSUBSCRIBE(tag string, patterns ...string) { _, _ = server.handleCommand(server.context, internal.EncodeCommand(cmd), connections[tag].writeConn, false, true) } -// PUBLISH publishes a message to the given channel. +// Publish publishes a message to the given channel. // // Parameters: // @@ -178,7 +178,7 @@ func (server *EchoVault) PUNSUBSCRIBE(tag string, patterns ...string) { // // Returns: "OK" when the publish is successful. This does not indicate whether each subscriber has received the message, // only that the message has been published. -func (server *EchoVault) PUBLISH(channel, message string) (string, error) { +func (server *EchoVault) Publish(channel, message string) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"PUBLISH", channel, message}), nil, false, true) if err != nil { return "", err @@ -186,14 +186,14 @@ func (server *EchoVault) PUBLISH(channel, message string) (string, error) { return internal.ParseStringResponse(b) } -// PUBSUB_CHANNELS returns the list of channels & patterns that match the glob pattern provided. +// PubSubChannels returns the list of channels & patterns that match the glob pattern provided. // // Parameters: // // `pattern` - string - The glob pattern used to match the channel names. // // Returns: A string slice of all the active channels and patterns (i.e. channels and patterns that have 1 or more subscribers). -func (server *EchoVault) PUBSUB_CHANNELS(pattern string) ([]string, error) { +func (server *EchoVault) PubSubChannels(pattern string) ([]string, error) { cmd := []string{"PUBSUB", "CHANNELS"} if pattern != "" { cmd = append(cmd, pattern) @@ -205,10 +205,10 @@ func (server *EchoVault) PUBSUB_CHANNELS(pattern string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// PUBSUB_NUMPAT returns the list of active patterns. +// PubSubNumPat returns the list of active patterns. // // Returns: An integer representing the number of all the active patterns (i.e. patterns that have 1 or more subscribers). -func (server *EchoVault) PUBSUB_NUMPAT() (int, error) { +func (server *EchoVault) PubSubNumPat() (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"PUBSUB", "NUMPAT"}), nil, false, true) if err != nil { return 0, err @@ -216,14 +216,14 @@ func (server *EchoVault) PUBSUB_NUMPAT() (int, error) { return internal.ParseIntegerResponse(b) } -// PUBSUB_NUMSUB returns the number of subscribers for each of the specified channels. +// PubSubNmSub returns the number of subscribers for each of the specified channels. // // Parameters: // // `channels` - ...string - The list of channels whose number of subscribers is to be checked. // // Returns: A map of map[string]int where the key is the channel name and the value is the number of subscribers. -func (server *EchoVault) PUBSUB_NUMSUB(channels ...string) (map[string]int, error) { +func (server *EchoVault) PubSubNmSub(channels ...string) (map[string]int, error) { cmd := append([]string{"PUBSUB", "NUMSUB"}, channels...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) diff --git a/pkg/echovault/api_set.go b/echovault/api_set.go similarity index 83% rename from pkg/echovault/api_set.go rename to echovault/api_set.go index 575c8e25..48ec7e0b 100644 --- a/pkg/echovault/api_set.go +++ b/echovault/api_set.go @@ -19,7 +19,7 @@ import ( "strconv" ) -// SADD adds member(s) to a set. If the set does not exist, a new sorted set is created with the +// SAdd adds member(s) to a set. If the set does not exist, a new sorted set is created with the // member(s). // // Parameters: @@ -33,7 +33,7 @@ import ( // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SADD(key string, members ...string) (int, error) { +func (server *EchoVault) SAdd(key string, members ...string) (int, error) { cmd := append([]string{"SADD", key}, members...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -42,7 +42,7 @@ func (server *EchoVault) SADD(key string, members ...string) (int, error) { return internal.ParseIntegerResponse(b) } -// SCARD Returns the cardinality of the set. +// SCard Returns the cardinality of the set. // // Parameters: // @@ -53,7 +53,7 @@ func (server *EchoVault) SADD(key string, members ...string) (int, error) { // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SCARD(key string) (int, error) { +func (server *EchoVault) SCard(key string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SCARD", key}), nil, false, true) if err != nil { return 0, err @@ -61,7 +61,7 @@ func (server *EchoVault) SCARD(key string) (int, error) { return internal.ParseIntegerResponse(b) } -// SDIFF Calculates the difference between the provided sets. Keys that don't exist or that are not sets +// SDiff Calculates the difference between the provided sets. Keys that don't exist or that are not sets // will be skipped. // // Parameters: @@ -75,7 +75,7 @@ func (server *EchoVault) SCARD(key string) (int, error) { // "value at is not a set" - when the provided key exists but is not a set. // // "key for base set does not exist" - if the first key is not a set. -func (server *EchoVault) SDIFF(keys ...string) ([]string, error) { +func (server *EchoVault) SDiff(keys ...string) ([]string, error) { cmd := append([]string{"SDIFF"}, keys...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -84,9 +84,9 @@ func (server *EchoVault) SDIFF(keys ...string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// SDIFFSTORE works like SDIFF but instead of returning the resulting set elements, the resulting set is stored +// SDiffStore works like SDiff but instead of returning the resulting set elements, the resulting set is stored // at the 'destination' key. -func (server *EchoVault) SDIFFSTORE(destination string, keys ...string) (int, error) { +func (server *EchoVault) SDiffStore(destination string, keys ...string) (int, error) { cmd := append([]string{"SDIFFSTORE", destination}, keys...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -95,7 +95,7 @@ func (server *EchoVault) SDIFFSTORE(destination string, keys ...string) (int, er return internal.ParseIntegerResponse(b) } -// SINTER Calculates the intersection between the provided sets. If any of the keys does not exist, +// SInter Calculates the intersection between the provided sets. If any of the keys does not exist, // then there is no intersection. // // Parameters: @@ -109,7 +109,7 @@ func (server *EchoVault) SDIFFSTORE(destination string, keys ...string) (int, er // "value at is not a set" - when the provided key exists but is not a set. // // "not enough sets in the keys provided" - when only one of the provided keys is a valid set. -func (server *EchoVault) SINTER(keys ...string) ([]string, error) { +func (server *EchoVault) SInter(keys ...string) ([]string, error) { cmd := append([]string{"SINTER"}, keys...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -118,7 +118,7 @@ func (server *EchoVault) SINTER(keys ...string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// SINTERCARD Calculates the cardinality of the intersection between the sets provided. +// SInterCard Calculates the cardinality of the intersection between the sets provided. // // Parameters: // @@ -133,7 +133,7 @@ func (server *EchoVault) SINTER(keys ...string) ([]string, error) { // "value at is not a set" - when the provided key exists but is not a set. // // "not enough sets in the keys provided" - when only one of the provided keys is a valid set. -func (server *EchoVault) SINTERCARD(keys []string, limit uint) (int, error) { +func (server *EchoVault) SInterCard(keys []string, limit uint) (int, error) { cmd := append([]string{"SINTERCARD"}, keys...) if limit > 0 { cmd = append(cmd, []string{"LIMIT", strconv.Itoa(int(limit))}...) @@ -145,9 +145,9 @@ func (server *EchoVault) SINTERCARD(keys []string, limit uint) (int, error) { return internal.ParseIntegerResponse(b) } -// SINTERSTORE works the same as SINTER but instead of returning the elements in the resulting set, it is stored +// SInterStore works the same as SInter but instead of returning the elements in the resulting set, it is stored // at the 'destination' key and the cardinality of the resulting set is returned. -func (server *EchoVault) SINTERSTORE(destination string, keys ...string) (int, error) { +func (server *EchoVault) SInterStore(destination string, keys ...string) (int, error) { cmd := append([]string{"SINTERSTORE", destination}, keys...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -156,7 +156,7 @@ func (server *EchoVault) SINTERSTORE(destination string, keys ...string) (int, e return internal.ParseIntegerResponse(b) } -// SISMEMBER Returns if member is contained in the set. +// SisMember Returns if member is contained in the set. // // Parameters: // @@ -169,7 +169,7 @@ func (server *EchoVault) SINTERSTORE(destination string, keys ...string) (int, e // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SISMEMBER(key, member string) (bool, error) { +func (server *EchoVault) SisMember(key, member string) (bool, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SISMEMBER", key, member}), nil, false, true) if err != nil { return false, err @@ -177,7 +177,7 @@ func (server *EchoVault) SISMEMBER(key, member string) (bool, error) { return internal.ParseBooleanResponse(b) } -// SMEMBERS Returns all the members of the specified set. +// SMembers Returns all the members of the specified set. // // Parameters: // @@ -188,7 +188,7 @@ func (server *EchoVault) SISMEMBER(key, member string) (bool, error) { // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SMEMBERS(key string) ([]string, error) { +func (server *EchoVault) SMembers(key string) ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SMEMBERS", key}), nil, false, true) if err != nil { return nil, err @@ -196,7 +196,7 @@ func (server *EchoVault) SMEMBERS(key string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// SMISMEMBER Returns the membership status of all the specified members. +// SMisMember Returns the membership status of all the specified members. // // Parameters: // @@ -210,7 +210,7 @@ func (server *EchoVault) SMEMBERS(key string) ([]string, error) { // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SMISMEMBER(key string, members ...string) ([]bool, error) { +func (server *EchoVault) SMisMember(key string, members ...string) ([]bool, error) { cmd := append([]string{"SMISMEMBER", key}, members...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -219,7 +219,7 @@ func (server *EchoVault) SMISMEMBER(key string, members ...string) ([]bool, erro return internal.ParseBooleanArrayResponse(b) } -// SMOVE Move the specified member from 'source' set to 'destination' set. +// SMove Move the specified member from 'source' set to 'destination' set. // // Parameters: // @@ -238,7 +238,7 @@ func (server *EchoVault) SMISMEMBER(key string, members ...string) ([]bool, erro // "source is not a set" - when the source key does not hold a set. // // "destination is not a set" - when the destination key does not hold a set. -func (server *EchoVault) SMOVE(source, destination, member string) (bool, error) { +func (server *EchoVault) SMove(source, destination, member string) (bool, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SMOVE", source, destination, member}), nil, false, true) if err != nil { return false, err @@ -246,7 +246,7 @@ func (server *EchoVault) SMOVE(source, destination, member string) (bool, error) return internal.ParseBooleanResponse(b) } -// SPOP Pop one or more elements from the set. +// SPop Pop one or more elements from the set. // // Parameters: // @@ -259,7 +259,7 @@ func (server *EchoVault) SMOVE(source, destination, member string) (bool, error) // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SPOP(key string, count uint) ([]string, error) { +func (server *EchoVault) SPop(key string, count uint) ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SPOP", key, strconv.Itoa(int(count))}), nil, false, true) if err != nil { return nil, err @@ -267,7 +267,7 @@ func (server *EchoVault) SPOP(key string, count uint) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// SRANDMEMBER Returns one or more random members from the set without removing them. +// SRandMember Returns one or more random members from the set without removing them. // // Parameters: // @@ -281,7 +281,7 @@ func (server *EchoVault) SPOP(key string, count uint) ([]string, error) { // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SRANDMEMBER(key string, count int) ([]string, error) { +func (server *EchoVault) SRandMember(key string, count int) ([]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SRANDMEMBER", key, strconv.Itoa(count)}), nil, false, true) if err != nil { return nil, err @@ -289,7 +289,7 @@ func (server *EchoVault) SRANDMEMBER(key string, count int) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// SREM Remove one or more members from a set. +// SRem Remove one or more members from a set. // // Parameters: // @@ -302,7 +302,7 @@ func (server *EchoVault) SRANDMEMBER(key string, count int) ([]string, error) { // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SREM(key string, members ...string) (int, error) { +func (server *EchoVault) SRem(key string, members ...string) (int, error) { cmd := append([]string{"SREM", key}, members...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -311,7 +311,7 @@ func (server *EchoVault) SREM(key string, members ...string) (int, error) { return internal.ParseIntegerResponse(b) } -// SUNION Calculates the union between the provided sets. Keys that don't exist or that are not sets +// SUnion Calculates the union between the provided sets. Keys that don't exist or that are not sets // will be skipped. // // Parameters: @@ -323,7 +323,7 @@ func (server *EchoVault) SREM(key string, members ...string) (int, error) { // Errors: // // "value at is not a set" - when the provided key exists but is not a set. -func (server *EchoVault) SUNION(keys ...string) ([]string, error) { +func (server *EchoVault) SUnion(keys ...string) ([]string, error) { cmd := append([]string{"SUNION"}, keys...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -332,9 +332,9 @@ func (server *EchoVault) SUNION(keys ...string) ([]string, error) { return internal.ParseStringArrayResponse(b) } -// SUNIONSTORE store works like SUNION but instead of returning the resulting elements, it stores the resulting +// SUnionStore store works like SUnion but instead of returning the resulting elements, it stores the resulting // set at the 'destination' key. The return value is an integer representing the cardinality of the new set. -func (server *EchoVault) SUNIONSTORE(destination string, keys ...string) (int, error) { +func (server *EchoVault) SUnionStore(destination string, keys ...string) (int, error) { cmd := append([]string{"SUNIONSTORE", destination}, keys...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { diff --git a/pkg/echovault/api_sorted_set.go b/echovault/api_sorted_set.go similarity index 85% rename from pkg/echovault/api_sorted_set.go rename to echovault/api_sorted_set.go index aaa1d169..9b220684 100644 --- a/pkg/echovault/api_sorted_set.go +++ b/echovault/api_sorted_set.go @@ -19,7 +19,7 @@ import ( "strconv" ) -// ZADDOptions allows you to modify the effects of the ZADD command. +// ZAddOptions allows you to modify the effects of the ZAdd command. // // "NX" only adds the member if it currently does not exist in the sorted set. This flag is mutually exclusive with the // "GT" and "LT" flags. The "NX" flag takes higher priority than the "XX" flag. @@ -34,9 +34,9 @@ import ( // "CH" modifies the result to return total number of members changed + added, instead of only new members added. When // this flag is set to true, only the number of members that have been updated will be returned. // -// "INCR" modifies the command to act like ZINCRBY, only one score/member pair can be specified in this mode. When this flag +// "INCR" modifies the command to act like ZIncrBy, only one score/member pair can be specified in this mode. When this flag // is provided, only one member/score pair is allowed. -type ZADDOptions struct { +type ZAddOptions struct { NX bool XX bool GT bool @@ -45,7 +45,7 @@ type ZADDOptions struct { INCR bool } -// ZINTEROptions allows you to modify the result of the ZINTER* and ZUNION* family of commands +// ZInterOptions allows you to modify the result of the ZInter* and ZUnion* family of commands // // Weights is a slice of float64 that determines the weights of each sorted set in the aggregation command. // each weight will be each weight will be applied to the sorted set at the corresponding index. @@ -57,29 +57,29 @@ type ZADDOptions struct { // "SUM" will add all the scores to place in the resulting sorted set. // // WithScores determines whether to return the scores of the resulting set. -type ZINTEROptions struct { +type ZInterOptions struct { Weights []float64 Aggregate string WithScores bool } -type ZINTERSTOREOptions ZINTEROptions -type ZUNIONOptions ZINTEROptions -type ZUNIONSTOREOptions ZINTEROptions +type ZInterStoreOptions ZInterOptions +type ZUnionOptions ZInterOptions +type ZUnionStoreOptions ZInterOptions -// ZMPOPOptions allows you to modify the result of the ZMPOP command. +// ZMPopOptions allows you to modify the result of the ZMPop command. // // Min instructs EchoVault to pop the minimum score elements. Min is higher priority than Max. // // Max instructs EchoVault to pop the maximum score elements. // // Count specifies the number of elements to pop. -type ZMPOPOptions struct { +type ZMPopOptions struct { Min bool Max bool Count uint } -// ZRANGEOptions allows you to modify the effects of the ZRANGE* family of commands. +// ZRangeOptions allows you to modify the effects of the ZRange* family of commands. // // WithScores specifies whether to return the associated scores. // @@ -87,17 +87,17 @@ type ZMPOPOptions struct { // // ByLex returns the elements within the lexicographical ranges specified. // -// Offset specifies the offset to from which to start the ZRANGE process. +// Offset specifies the offset to from which to start the ZRange process. // // Count specifies the number of elements to return. -type ZRANGEOptions struct { +type ZRangeOptions struct { WithScores bool ByScore bool ByLex bool Offset uint Count uint } -type ZRANGESTOREOptions ZRANGEOptions +type ZRangeStoreOptions ZRangeOptions func buildMemberScoreMap(arr [][]string, withscores bool) (map[string]float64, error) { result := make(map[string]float64, len(arr)) @@ -134,7 +134,7 @@ func buildIntegerScoreMap(arr [][]string, withscores bool) (map[int]float64, err return result, nil } -// ZADD adds member(s) to a sorted set. If the sorted set does not exist, a new sorted set is created with the +// ZAdd adds member(s) to a sorted set. If the sorted set does not exist, a new sorted set is created with the // member(s). // // Parameters: @@ -143,7 +143,7 @@ func buildIntegerScoreMap(arr [][]string, withscores bool) (map[int]float64, err // // `members` - map[string]float64 - a map of the members to add. The key is the string and the value is a float64 score. // -// `options` - ZADDOptions +// `options` - ZAddOptions // // Returns: The number of members added, or the number of members updated in the "CH" flag is true. // @@ -151,11 +151,11 @@ func buildIntegerScoreMap(arr [][]string, withscores bool) (map[int]float64, err // // "GT/LT flags not allowed if NX flag is provided" - when GT/LT flags are provided alongside NX flag. // -// "cannot pass more than one score/member pair when INCR flag is provided" - when INCR flag is provided and more than -// one member-score pair is provided. +// "cannot pass more than one score/member pair when INCR flag is provided" - when INCR flag is provided with more than +// one member-score pair. // // "value at is not a sorted set" - when the provided key exists but is not a sorted set -func (server *EchoVault) ZADD(key string, members map[string]float64, options ZADDOptions) (int, error) { +func (server *EchoVault) ZAdd(key string, members map[string]float64, options ZAddOptions) (int, error) { cmd := []string{"ZADD", key} switch { @@ -192,7 +192,7 @@ func (server *EchoVault) ZADD(key string, members map[string]float64, options ZA return internal.ParseIntegerResponse(b) } -// ZCARD returns the cardinality of the sorted set. +// ZCard returns the cardinality of the sorted set. // // Parameters: // @@ -203,7 +203,7 @@ func (server *EchoVault) ZADD(key string, members map[string]float64, options ZA // Errors: // // "value at is not a sorted set" - when the provided key exists but is not a sorted set -func (server *EchoVault) ZCARD(key string) (int, error) { +func (server *EchoVault) ZCard(key string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"ZCARD", key}), nil, false, true) if err != nil { return 0, err @@ -211,7 +211,7 @@ func (server *EchoVault) ZCARD(key string) (int, error) { return internal.ParseIntegerResponse(b) } -// ZCOUNT returns the number of elements in the sorted set key with scores in the range of min and max. +// ZCount returns the number of elements in the sorted set key with scores in the range of min and max. // // Parameters: // @@ -226,7 +226,7 @@ func (server *EchoVault) ZCARD(key string) (int, error) { // Errors: // // "value at is not a sorted set" - when the provided key exists but is not a sorted set -func (server *EchoVault) ZCOUNT(key string, min, max float64) (int, error) { +func (server *EchoVault) ZCount(key string, min, max float64) (int, error) { cmd := []string{ "ZCOUNT", key, @@ -240,7 +240,7 @@ func (server *EchoVault) ZCOUNT(key string, min, max float64) (int, error) { return internal.ParseIntegerResponse(b) } -// ZDIFF Calculates the difference between the sorted sets and returns the resulting sorted set. +// ZDiff Calculates the difference between the sorted sets and returns the resulting sorted set. // All keys that are non-existed are skipped. // // Parameters: @@ -255,7 +255,7 @@ func (server *EchoVault) ZCOUNT(key string, min, max float64) (int, error) { // Errors: // // "value at is not a sorted set" - when the provided key exists but is not a sorted set. -func (server *EchoVault) ZDIFF(withscores bool, keys ...string) (map[string]float64, error) { +func (server *EchoVault) ZDiff(withscores bool, keys ...string) (map[string]float64, error) { cmd := append([]string{"ZDIFF"}, keys...) if withscores { cmd = append(cmd, "WITHSCORES") @@ -273,7 +273,7 @@ func (server *EchoVault) ZDIFF(withscores bool, keys ...string) (map[string]floa return buildMemberScoreMap(arr, withscores) } -// ZDIFFSTORE Calculates the difference between the sorted sets and stores the resulting sorted set at 'destination'. +// ZDiffStore Calculates the difference between the sorted sets and stores the resulting sorted set at 'destination'. // Non-existent keys will be skipped. // // Parameters: @@ -287,7 +287,7 @@ func (server *EchoVault) ZDIFF(withscores bool, keys ...string) (map[string]floa // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZDIFFSTORE(destination string, keys ...string) (int, error) { +func (server *EchoVault) ZDiffStore(destination string, keys ...string) (int, error) { cmd := append([]string{"ZDIFFSTORE", destination}, keys...) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -296,21 +296,21 @@ func (server *EchoVault) ZDIFFSTORE(destination string, keys ...string) (int, er return internal.ParseIntegerResponse(b) } -// ZINTER Calculates the intersection between the sorted sets and returns the resulting sorted set. +// ZInter Calculates the intersection between the sorted sets and returns the resulting sorted set. // if any of the keys provided are non-existent, an empty map is returned. // // Parameters: // // `keys` - []string - the keys to the sorted sets to be used in calculating the intersection. // -// `options` - ZINTEROptions +// `options` - ZInterOptions // // Returns: A map representing the resulting sorted set where the key is the member and the value is a float64 score. // // Errors: // // "value at is not a sorted set" - when the provided key exists but is not a sorted set. -func (server *EchoVault) ZINTER(keys []string, options ZINTEROptions) (map[string]float64, error) { +func (server *EchoVault) ZInter(keys []string, options ZInterOptions) (map[string]float64, error) { cmd := append([]string{"ZINTER"}, keys...) if len(options.Weights) > 0 { @@ -341,7 +341,7 @@ func (server *EchoVault) ZINTER(keys []string, options ZINTEROptions) (map[strin return buildMemberScoreMap(arr, options.WithScores) } -// ZINTERSTORE Calculates the intersection between the sorted sets and stores the resulting sorted set at 'destination'. +// ZInterStore Calculates the intersection between the sorted sets and stores the resulting sorted set at 'destination'. // If any of the keys does not exist, the operation is abandoned. // // Parameters: @@ -350,20 +350,20 @@ func (server *EchoVault) ZINTER(keys []string, options ZINTEROptions) (map[strin // // `keys` - []string - the keys to the sorted sets to be used in calculating the intersection. // -// `options` - ZINTERSTOREOptions +// `options` - ZInterStoreOptions // // Returns: The cardinality of the new sorted set. // // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZINTERSTORE(destination string, keys []string, options ZINTERSTOREOptions) (int, error) { +func (server *EchoVault) ZInterStore(destination string, keys []string, options ZInterStoreOptions) (int, error) { cmd := append([]string{"ZINTERSTORE", destination}, keys...) if len(options.Weights) > 0 { cmd = append(cmd, "WEIGHTS") for _, weight := range options.Weights { - cmd = append(cmd, strconv.FormatFloat(float64(weight), 'f', -1, 64)) + cmd = append(cmd, strconv.FormatFloat(weight, 'f', -1, 64)) } } @@ -383,27 +383,27 @@ func (server *EchoVault) ZINTERSTORE(destination string, keys []string, options return internal.ParseIntegerResponse(b) } -// ZUNION Calculates the union between the sorted sets and returns the resulting sorted set. +// ZUnion Calculates the union between the sorted sets and returns the resulting sorted set. // if any of the keys provided are non-existent, an error is returned. // // Parameters: // // `keys` - []string - the keys to the sorted sets to be used in calculating the union. // -// `options` - ZUNIONOptions +// `options` - ZUnionOptions // // Returns: A map representing the resulting sorted set where the key is the member and the value is a float64 score. // // Errors: // // "value at is not a sorted set" - when the provided key exists but is not a sorted set. -func (server *EchoVault) ZUNION(keys []string, options ZUNIONOptions) (map[string]float64, error) { +func (server *EchoVault) ZUnion(keys []string, options ZUnionOptions) (map[string]float64, error) { cmd := append([]string{"ZUNION"}, keys...) if len(options.Weights) > 0 { cmd = append(cmd, "WEIGHTS") for _, weight := range options.Weights { - cmd = append(cmd, strconv.FormatFloat(float64(weight), 'f', -1, 64)) + cmd = append(cmd, strconv.FormatFloat(weight, 'f', -1, 64)) } } @@ -428,7 +428,7 @@ func (server *EchoVault) ZUNION(keys []string, options ZUNIONOptions) (map[strin return buildMemberScoreMap(arr, options.WithScores) } -// ZUNIONSTORE Calculates the union between the sorted sets and stores the resulting sorted set at 'destination'. +// ZUnionStore Calculates the union between the sorted sets and stores the resulting sorted set at 'destination'. // Non-existent keys will be skipped. // // Parameters: @@ -437,14 +437,14 @@ func (server *EchoVault) ZUNION(keys []string, options ZUNIONOptions) (map[strin // // `keys` - []string - the keys to the sorted sets to be used in calculating the union. // -// `options` - ZUNIONSTOREOptions +// `options` - ZUnionStoreOptions // // Returns: The cardinality of the new sorted set. // // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZUNIONSTORE(destination string, keys []string, options ZUNIONSTOREOptions) (int, error) { +func (server *EchoVault) ZUnionStore(destination string, keys []string, options ZUnionStoreOptions) (int, error) { cmd := append([]string{"ZUNIONSTORE", destination}, keys...) if len(options.Weights) > 0 { @@ -470,7 +470,7 @@ func (server *EchoVault) ZUNIONSTORE(destination string, keys []string, options return internal.ParseIntegerResponse(b) } -// ZINCRBY Increments the score of the specified sorted set's member by the increment. If the member does not exist, it is created. +// ZIncrBy Increments the score of the specified sorted set's member by the increment. If the member does not exist, it is created. // If the key does not exist, it is created with new sorted set and the member added with the increment as its score. // // Parameters: @@ -486,7 +486,7 @@ func (server *EchoVault) ZUNIONSTORE(destination string, keys []string, options // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZINCRBY(key string, increment float64, member string) (float64, error) { +func (server *EchoVault) ZIncrBy(key string, increment float64, member string) (float64, error) { cmd := []string{"ZINCRBY", key, strconv.FormatFloat(increment, 'f', -1, 64), member} b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -499,21 +499,21 @@ func (server *EchoVault) ZINCRBY(key string, increment float64, member string) ( return f, nil } -// ZMPOP Pop a 'count' elements from multiple sorted sets. MIN or MAX determines whether to pop elements with the lowest +// ZMPop Pop a 'count' elements from multiple sorted sets. MIN or MAX determines whether to pop elements with the lowest // or highest scores respectively. // // Parameters: // // `keys` - []string - the keys to the sorted sets to pop from. // -// `options` - ZMPOPOptions +// `options` - ZMPopOptions // // Returns: A 2-dimensional slice where each slice contains the member and score at the 0 and 1 indices respectively. // // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZMPOP(keys []string, options ZMPOPOptions) ([][]string, error) { +func (server *EchoVault) ZMPop(keys []string, options ZMPopOptions) ([][]string, error) { cmd := append([]string{"ZMPOP"}, keys...) switch { @@ -540,7 +540,7 @@ func (server *EchoVault) ZMPOP(keys []string, options ZMPOPOptions) ([][]string, return internal.ParseNestedStringArrayResponse(b) } -// ZMSCORE Returns the associated scores of the specified member in the sorted set. +// ZMScore Returns the associated scores of the specified member in the sorted set. // // Parameters: // @@ -555,7 +555,7 @@ func (server *EchoVault) ZMPOP(keys []string, options ZMPOPOptions) ([][]string, // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZMSCORE(key string, members ...string) ([]interface{}, error) { +func (server *EchoVault) ZMScore(key string, members ...string) ([]interface{}, error) { cmd := []string{"ZMSCORE", key} for _, member := range members { cmd = append(cmd, member) @@ -587,7 +587,7 @@ func (server *EchoVault) ZMSCORE(key string, members ...string) ([]interface{}, return scores, nil } -// ZLEXCOUNT returns the number of elements in the sorted set within the lexicographical range between min and max. +// ZLexCount returns the number of elements in the sorted set within the lexicographical range between min and max. // This function only returns a non-zero value if all the members have the same score. // // Parameters: @@ -604,7 +604,7 @@ func (server *EchoVault) ZMSCORE(key string, members ...string) ([]interface{}, // Errors: // // "value at is not a sorted set" - when the provided key exists but is not a sorted set -func (server *EchoVault) ZLEXCOUNT(key, min, max string) (int, error) { +func (server *EchoVault) ZLexCount(key, min, max string) (int, error) { cmd := []string{"ZLEXCOUNT", key, min, max} b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -613,7 +613,7 @@ func (server *EchoVault) ZLEXCOUNT(key, min, max string) (int, error) { return internal.ParseIntegerResponse(b) } -// ZPOPMAX Removes and returns 'count' number of members in the sorted set with the highest scores. Default count is 1. +// ZPopMax Removes and returns 'count' number of members in the sorted set with the highest scores. Default count is 1. // // Parameters: // @@ -629,7 +629,7 @@ func (server *EchoVault) ZLEXCOUNT(key, min, max string) (int, error) { // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZPOPMAX(key string, count uint) ([][]string, error) { +func (server *EchoVault) ZPopMax(key string, count uint) ([][]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"ZPOPMAX", key, strconv.Itoa(int(count))}), nil, false, true) if err != nil { return nil, err @@ -637,7 +637,7 @@ func (server *EchoVault) ZPOPMAX(key string, count uint) ([][]string, error) { return internal.ParseNestedStringArrayResponse(b) } -// ZPOPMIN Removes and returns 'count' number of members in the sorted set with the lowest scores. Default count is 1. +// ZPopMin Removes and returns 'count' number of members in the sorted set with the lowest scores. Default count is 1. // // Parameters: // @@ -653,7 +653,7 @@ func (server *EchoVault) ZPOPMAX(key string, count uint) ([][]string, error) { // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZPOPMIN(key string, count uint) ([][]string, error) { +func (server *EchoVault) ZPopMin(key string, count uint) ([][]string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"ZPOPMIN", key, strconv.Itoa(int(count))}), nil, false, true) if err != nil { return nil, err @@ -661,7 +661,7 @@ func (server *EchoVault) ZPOPMIN(key string, count uint) ([][]string, error) { return internal.ParseNestedStringArrayResponse(b) } -// ZRANDMEMBER Returns a list of length equivalent to 'count' containing random members of the sorted set. +// ZRandMember Returns a list of length equivalent to 'count' containing random members of the sorted set. // If count is negative, repeated elements are allowed. If count is positive, the returned elements will be distinct. // The default count is 1. If a count of 0 is passed, it will be ignored. // @@ -682,7 +682,7 @@ func (server *EchoVault) ZPOPMIN(key string, count uint) ([][]string, error) { // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZRANDMEMBER(key string, count int, withscores bool) ([][]string, error) { +func (server *EchoVault) ZRandMember(key string, count int, withscores bool) ([][]string, error) { cmd := []string{"ZRANDMEMBER", key} if count != 0 { cmd = append(cmd, strconv.Itoa(count)) @@ -699,7 +699,7 @@ func (server *EchoVault) ZRANDMEMBER(key string, count int, withscores bool) ([] return internal.ParseNestedStringArrayResponse(b) } -// ZRANK Returns the rank of the specified member in the sorted set. The rank is derived from organising the members +// ZRank Returns the rank of the specified member in the sorted set. The rank is derived from organising the members // in descending order of score. // // Parameters: @@ -717,7 +717,7 @@ func (server *EchoVault) ZRANDMEMBER(key string, count int, withscores bool) ([] // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZRANK(key string, member string, withscores bool) (map[int]float64, error) { +func (server *EchoVault) ZRank(key string, member string, withscores bool) (map[int]float64, error) { cmd := []string{"ZRANK", key, member} if withscores { cmd = append(cmd, "WITHSCORES") @@ -752,9 +752,9 @@ func (server *EchoVault) ZRANK(key string, member string, withscores bool) (map[ return res, nil } -// ZREVRANK works the same as ZRANK but derives the member's rank based on ascending order of +// ZRevRank works the same as ZRank but derives the member's rank based on ascending order of // the members' scores. -func (server *EchoVault) ZREVRANK(key string, member string, withscores bool) (map[int]float64, error) { +func (server *EchoVault) ZRevRank(key string, member string, withscores bool) (map[int]float64, error) { cmd := []string{"ZREVRANK", key, member} if withscores { cmd = append(cmd, "WITHSCORES") @@ -770,7 +770,7 @@ func (server *EchoVault) ZREVRANK(key string, member string, withscores bool) (m return buildIntegerScoreMap(arr, withscores) } -// ZSCORE Returns the score of the member in the sorted set. +// ZScore Returns the score of the member in the sorted set. // // Parameters: // @@ -784,7 +784,7 @@ func (server *EchoVault) ZREVRANK(key string, member string, withscores bool) (m // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZSCORE(key string, member string) (interface{}, error) { +func (server *EchoVault) ZScore(key string, member string) (interface{}, error) { cmd := []string{"ZSCORE", key, member} b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) if err != nil { @@ -808,7 +808,7 @@ func (server *EchoVault) ZSCORE(key string, member string) (interface{}, error) return score, nil } -// ZREM Removes the listed members from the sorted set. +// ZRem Removes the listed members from the sorted set. // // Parameters: // @@ -821,7 +821,7 @@ func (server *EchoVault) ZSCORE(key string, member string) (interface{}, error) // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZREM(key string, members ...string) (int, error) { +func (server *EchoVault) ZRem(key string, members ...string) (int, error) { cmd := []string{"ZREM", key} for _, member := range members { cmd = append(cmd, member) @@ -833,7 +833,7 @@ func (server *EchoVault) ZREM(key string, members ...string) (int, error) { return internal.ParseIntegerResponse(b) } -// ZREMRANGEBYSCORE Removes the elements whose scores are in the range between min and max. +// ZRemRangeByScore Removes the elements whose scores are in the range between min and max. // // Parameters: // @@ -848,7 +848,7 @@ func (server *EchoVault) ZREM(key string, members ...string) (int, error) { // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZREMRANGEBYSCORE(key string, min float64, max float64) (int, error) { +func (server *EchoVault) ZRemRangeByScore(key string, min float64, max float64) (int, error) { cmd := []string{ "ZREMRANGEBYSCORE", key, @@ -864,7 +864,7 @@ func (server *EchoVault) ZREMRANGEBYSCORE(key string, min float64, max float64) return internal.ParseIntegerResponse(b) } -// ZRANGE Returns the range of elements in the sorted set. +// ZRange Returns the range of elements in the sorted set. // // Parameters: // @@ -874,14 +874,14 @@ func (server *EchoVault) ZREMRANGEBYSCORE(key string, min float64, max float64) // // `stop` - string - The maximum boundary. // -// `options` - ZRANGEOptions +// `options` - ZRangeOptions // // Returns: A map of map[string]float64 where the key is the member and the value is its score. // // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZRANGE(key, start, stop string, options ZRANGEOptions) (map[string]float64, error) { +func (server *EchoVault) ZRange(key, start, stop string, options ZRangeOptions) (map[string]float64, error) { cmd := []string{"ZRANGE", key, start, stop} switch { @@ -914,7 +914,7 @@ func (server *EchoVault) ZRANGE(key, start, stop string, options ZRANGEOptions) return buildMemberScoreMap(arr, options.WithScores) } -// ZRANGESTORE Works like ZRANGE but stores the result in at the 'destination' key. +// ZRangeStore Works like ZRange but stores the result in at the 'destination' key. // // Parameters: // @@ -926,14 +926,14 @@ func (server *EchoVault) ZRANGE(key, start, stop string, options ZRANGEOptions) // // `stop` - string - The maximum boundary. // -// `options` - ZRANGESTOREOptions +// `options` - ZRangeStoreOptions // // Returns: The cardinality of the new sorted set. // // Errors: // // "value at is not a sorted set" - when a key exists but is not a sorted set. -func (server *EchoVault) ZRANGESTORE(destination, source, start, stop string, options ZRANGESTOREOptions) (int, error) { +func (server *EchoVault) ZRangeStore(destination, source, start, stop string, options ZRangeStoreOptions) (int, error) { cmd := []string{"ZRANGESTORE", destination, source, start, stop} switch { diff --git a/pkg/echovault/api_string.go b/echovault/api_string.go similarity index 83% rename from pkg/echovault/api_string.go rename to echovault/api_string.go index 40a68868..8f33b013 100644 --- a/pkg/echovault/api_string.go +++ b/echovault/api_string.go @@ -19,7 +19,7 @@ import ( "strconv" ) -// SETRANGE replaces a portion of the string at the provided key starting at the offset with a new string. +// SetRange replaces a portion of the string at the provided key starting at the offset with a new string. // If the string does not exist, a new string is created. // // Returns: The length of the new string as an integers. @@ -27,7 +27,7 @@ import ( // Errors: // // - "value at key is not a string" when the key provided does not hold a string. -func (server *EchoVault) SETRANGE(key string, offset int, new string) (int, error) { +func (server *EchoVault) SetRange(key string, offset int, new string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SETRANGE", key, strconv.Itoa(offset), new}), nil, false, true) if err != nil { return 0, err @@ -35,14 +35,14 @@ func (server *EchoVault) SETRANGE(key string, offset int, new string) (int, erro return internal.ParseIntegerResponse(b) } -// STRLEN returns the length of the string at the provided key. +// StrLen returns the length of the string at the provided key. // // Returns: The length of the string as an integer. // // Errors: // // - "value at key is not a string" - when the value at the keys is not a string. -func (server *EchoVault) STRLEN(key string) (int, error) { +func (server *EchoVault) StrLen(key string) (int, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"STRLEN", key}), nil, false, true) if err != nil { return 0, err @@ -50,7 +50,7 @@ func (server *EchoVault) STRLEN(key string) (int, error) { return internal.ParseIntegerResponse(b) } -// SUBSTR returns a substring from the string at the key. +// SubStr returns a substring from the string at the key. // The start and end indices are integers that specify the lower and upper bound respectively. // // Returns: The substring from the start index to the end index. @@ -60,7 +60,7 @@ func (server *EchoVault) STRLEN(key string) (int, error) { // - "key does not exist" - when the key does not exist. // // - "value at key is not a string" - when the value at the keys is not a string. -func (server *EchoVault) SUBSTR(key string, start, end int) (string, error) { +func (server *EchoVault) SubStr(key string, start, end int) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SUBSTR", key, strconv.Itoa(start), strconv.Itoa(end)}), nil, false, true) if err != nil { return "", err @@ -68,8 +68,8 @@ func (server *EchoVault) SUBSTR(key string, start, end int) (string, error) { return internal.ParseStringResponse(b) } -// GETRANGE works the same as SUBSTR. -func (server *EchoVault) GETRANGE(key string, start, end int) (string, error) { +// GetRange works the same as SubStr. +func (server *EchoVault) GetRange(key string, start, end int) (string, error) { b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"GETRANGE", key, strconv.Itoa(start), strconv.Itoa(end)}), nil, false, true) if err != nil { return "", err diff --git a/pkg/echovault/cluster.go b/echovault/cluster.go similarity index 100% rename from pkg/echovault/cluster.go rename to echovault/cluster.go diff --git a/pkg/config/config.go b/echovault/config.go similarity index 93% rename from pkg/config/config.go rename to echovault/config.go index 07c77549..aa4130e8 100644 --- a/pkg/config/config.go +++ b/echovault/config.go @@ -1,4 +1,4 @@ -package config +package echovault import ( "github.com/echovault/echovault/internal/config" diff --git a/pkg/echovault/echovault.go b/echovault/echovault.go similarity index 98% rename from pkg/echovault/echovault.go rename to echovault/echovault.go index b5b1ba34..97313198 100644 --- a/pkg/echovault/echovault.go +++ b/echovault/echovault.go @@ -24,6 +24,7 @@ import ( "github.com/echovault/echovault/internal/aof" "github.com/echovault/echovault/internal/clock" "github.com/echovault/echovault/internal/config" + "github.com/echovault/echovault/internal/constants" "github.com/echovault/echovault/internal/eviction" "github.com/echovault/echovault/internal/memberlist" "github.com/echovault/echovault/internal/modules/acl" @@ -38,7 +39,6 @@ import ( str "github.com/echovault/echovault/internal/modules/string" "github.com/echovault/echovault/internal/raft" "github.com/echovault/echovault/internal/snapshot" - "github.com/echovault/echovault/pkg/constants" "io" "log" "net" @@ -185,6 +185,10 @@ func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) { Config: echovault.config, EchoVault: echovault, GetCommand: echovault.getCommand, + CreateKeyAndLock: echovault.CreateKeyAndLock, + SetValue: echovault.SetValue, + SetExpiry: echovault.SetExpiry, + KeyUnlock: echovault.KeyUnlock, DeleteKey: echovault.DeleteKey, StartSnapshot: echovault.startSnapshot, FinishSnapshot: echovault.finishSnapshot, @@ -476,7 +480,7 @@ func (server *EchoVault) handleConnection(conn net.Conn) { // Start starts the EchoVault instance's TCP listener. // This allows the instance to accept connections handle client commands over TCP. // -// You can still use command functions like echovault.SET if you're embedding EchoVault in you application. +// You can still use command functions like echovault.Set if you're embedding EchoVault in your application. // However, if you'd like to also accept TCP request on the same instance, you must call this function. func (server *EchoVault) Start() { server.startTCP() diff --git a/pkg/echovault/keyspace.go b/echovault/keyspace.go similarity index 99% rename from pkg/echovault/keyspace.go rename to echovault/keyspace.go index 1ba9d542..3dbbb4d2 100644 --- a/pkg/echovault/keyspace.go +++ b/echovault/keyspace.go @@ -19,7 +19,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "log" "math/rand" "runtime" @@ -245,7 +245,7 @@ func (server *EchoVault) SetExpiry(ctx context.Context, key string, expireAt tim } } -// RemoveExpiry is called by commands that remove key expiry (e.g. PERSIST). +// RemoveExpiry is called by commands that remove key expiry (e.g. Persist). // The key must be locked prior ro calling this function. func (server *EchoVault) RemoveExpiry(_ context.Context, key string) { // Reset expiry time diff --git a/pkg/echovault/modules.go b/echovault/modules.go similarity index 95% rename from pkg/echovault/modules.go rename to echovault/modules.go index f228b371..a13aa412 100644 --- a/pkg/echovault/modules.go +++ b/echovault/modules.go @@ -19,7 +19,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "net" "strings" ) @@ -73,7 +73,11 @@ func (server *EchoVault) handleCommand(ctx context.Context, message []byte, conn synchronize := command.Sync handler := command.HandlerFunc - subCommand, ok := internal.GetSubCommand(command, cmd).(internal.SubCommand) + sc, err := internal.GetSubCommand(command, cmd) + if err != nil { + return nil, err + } + subCommand, ok := sc.(internal.SubCommand) if ok { synchronize = subCommand.Sync handler = subCommand.HandlerFunc diff --git a/internal/config/config.go b/internal/config/config.go index 82d8c56e..205b047a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -20,7 +20,7 @@ import ( "flag" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "log" "os" "path" diff --git a/internal/config/default.go b/internal/config/default.go index 7daf4353..e50c2171 100644 --- a/internal/config/default.go +++ b/internal/config/default.go @@ -1,7 +1,7 @@ package config import ( - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "time" ) diff --git a/pkg/constants/const.go b/internal/constants/const.go similarity index 100% rename from pkg/constants/const.go rename to internal/constants/const.go diff --git a/internal/modules/acl/acl.go b/internal/modules/acl/acl.go index f2e158ed..5dc7d644 100644 --- a/internal/modules/acl/acl.go +++ b/internal/modules/acl/acl.go @@ -22,7 +22,7 @@ import ( "fmt" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "github.com/gobwas/glob" "gopkg.in/yaml.v3" "log" @@ -193,7 +193,7 @@ func (acl *ACL) DeleteUser(_ context.Context, usernames []string) error { } } // Skip if the current username was not found in the ACL - if username != user.Username { + if user == nil { continue } // Terminate every connection attached to this user diff --git a/internal/modules/acl/commands.go b/internal/modules/acl/commands.go index 64cb5c3a..e155ed67 100644 --- a/internal/modules/acl/commands.go +++ b/internal/modules/acl/commands.go @@ -19,7 +19,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "gopkg.in/yaml.v3" "log" "os" @@ -495,8 +495,8 @@ func Commands() []internal.Command { Categories: []string{constants.ConnectionCategory, constants.SlowCategory}, Description: "(AUTH [username] password) Authenticates the connection", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -510,8 +510,8 @@ func Commands() []internal.Command { Categories: []string{}, Description: "Access-Control-List commands", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -525,8 +525,8 @@ func Commands() []internal.Command { Description: `(ACL CAT [category]) List all the categories. If the optional category is provided, list all the commands in the category`, Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -540,8 +540,8 @@ If the optional category is provided, list all the commands in the category`, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory}, Description: "(ACL USERS) List all usernames of the configured ACL users", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -555,8 +555,8 @@ If the optional category is provided, list all the commands in the category`, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory}, Description: "(ACL SETUSER) Configure a new or existing user", Sync: true, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -570,8 +570,8 @@ If the optional category is provided, list all the commands in the category`, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory}, Description: "(ACL GETUSER username) List the ACL rules of a user", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -585,8 +585,8 @@ If the optional category is provided, list all the commands in the category`, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory}, Description: "(ACL DELUSER username [username ...]) Deletes users and terminates their connections. Cannot delete default user", Sync: true, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -600,8 +600,8 @@ If the optional category is provided, list all the commands in the category`, Categories: []string{constants.FastCategory}, Description: "(ACL WHOAMI) Returns the authenticated user of the current connection", Sync: true, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -615,8 +615,8 @@ If the optional category is provided, list all the commands in the category`, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory}, Description: "(ACL LIST) Dumps effective acl rules in acl config file format", Sync: true, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -633,8 +633,8 @@ If the optional category is provided, list all the commands in the category`, When 'MERGE' is passed, users from config file who share a username with users in memory will be merged. When 'REPLACE' is passed, users from config file who share a username with users in memory will replace the user in memory.`, Sync: true, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -648,8 +648,8 @@ When 'REPLACE' is passed, users from config file who share a username with users Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory}, Description: "(ACL SAVE) Saves the effective ACL rules the configured ACL config file", Sync: true, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), diff --git a/internal/modules/admin/commands.go b/internal/modules/admin/commands.go index 26b87dc3..18591ba2 100644 --- a/internal/modules/admin/commands.go +++ b/internal/modules/admin/commands.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "github.com/gobwas/glob" "slices" "strings" @@ -197,8 +197,8 @@ func Commands() []internal.Command { Categories: []string{constants.AdminCategory, constants.SlowCategory}, Description: "Get a list of all the commands in available on the echovault with categories and descriptions", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -212,8 +212,8 @@ func Commands() []internal.Command { Categories: []string{}, Description: "Commands pertaining to echovault commands", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -226,8 +226,8 @@ func Commands() []internal.Command { Categories: []string{constants.SlowCategory, constants.ConnectionCategory}, Description: "Get command documentation", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -241,8 +241,8 @@ func Commands() []internal.Command { Categories: []string{constants.SlowCategory}, Description: "Get the dumber of commands in the echovault", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -257,8 +257,8 @@ func Commands() []internal.Command { Description: `(COMMAND LIST [FILTERBY ]) Get the list of command names. Allows for filtering by ACL category or glob pattern.`, Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -274,8 +274,8 @@ Allows for filtering by ACL category or glob pattern.`, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory}, Description: "(SAVE) Trigger a snapshot save", Sync: true, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -294,8 +294,8 @@ Allows for filtering by ACL category or glob pattern.`, Categories: []string{constants.AdminCategory, constants.FastCategory, constants.DangerousCategory}, Description: "(LASTSAVE) Get unix timestamp for the latest snapshot in milliseconds.", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -315,8 +315,8 @@ Allows for filtering by ACL category or glob pattern.`, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory}, Description: "(REWRITEAOF) Trigger re-writing of append process", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), diff --git a/internal/modules/connection/commands.go b/internal/modules/connection/commands.go index d3ddf334..03312838 100644 --- a/internal/modules/connection/commands.go +++ b/internal/modules/connection/commands.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" ) func handlePing(params internal.HandlerFuncParams) ([]byte, error) { @@ -40,8 +40,8 @@ func Commands() []internal.Command { Categories: []string{constants.FastCategory, constants.ConnectionCategory}, Description: "(PING [value]) Ping the echovault. If a value is provided, the value will be echoed.", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), diff --git a/internal/modules/generic/commands.go b/internal/modules/generic/commands.go index 49c0bbb4..9c1ae96a 100644 --- a/internal/modules/generic/commands.go +++ b/internal/modules/generic/commands.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "log" "strconv" "strings" @@ -46,7 +46,7 @@ func handleSet(params internal.HandlerFuncParams) ([]byte, error) { return nil, err } - // If GET is provided, the response should be the current stored value. + // If Get is provided, the response should be the current stored value. // If there's no current value, then the response should be nil. if options.get { if !params.KeyExists(params.Context, key) { diff --git a/internal/modules/generic/key_funcs.go b/internal/modules/generic/key_funcs.go index e9a42d95..875c34a4 100644 --- a/internal/modules/generic/key_funcs.go +++ b/internal/modules/generic/key_funcs.go @@ -17,23 +17,23 @@ package generic import ( "errors" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" ) -func setKeyFunc(cmd []string) (internal.AccessKeys, error) { +func setKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 || len(cmd) > 7 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func msetKeyFunc(cmd []string) (internal.AccessKeys, error) { +func msetKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd[1:])%2 != 0 { - return internal.AccessKeys{}, errors.New("each key must be paired with a value") + return internal.KeyExtractionFuncResult{}, errors.New("each key must be paired with a value") } var keys []string for i, key := range cmd[1:] { @@ -41,95 +41,95 @@ func msetKeyFunc(cmd []string) (internal.AccessKeys, error) { keys = append(keys, key) } } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: keys, }, nil } -func getKeyFunc(cmd []string) (internal.AccessKeys, error) { +func getKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func mgetKeyFunc(cmd []string) (internal.AccessKeys, error) { +func mgetKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func delKeyFunc(cmd []string) (internal.AccessKeys, error) { +func delKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:], }, nil } -func persistKeyFunc(cmd []string) (internal.AccessKeys, error) { +func persistKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:], }, nil } -func expireTimeKeyFunc(cmd []string) (internal.AccessKeys, error) { +func expireTimeKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func ttlKeyFunc(cmd []string) (internal.AccessKeys, error) { +func ttlKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func expireKeyFunc(cmd []string) (internal.AccessKeys, error) { +func expireKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 || len(cmd) > 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func expireAtKeyFunc(cmd []string) (internal.AccessKeys, error) { +func expireAtKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 || len(cmd) > 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], diff --git a/internal/modules/hash/commands.go b/internal/modules/hash/commands.go index 5a679d2e..5924321b 100644 --- a/internal/modules/hash/commands.go +++ b/internal/modules/hash/commands.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "math/rand" "slices" "strconv" diff --git a/internal/modules/hash/key_funcs.go b/internal/modules/hash/key_funcs.go index 847ea9cd..e259c208 100644 --- a/internal/modules/hash/key_funcs.go +++ b/internal/modules/hash/key_funcs.go @@ -17,142 +17,142 @@ package hash import ( "errors" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" ) -func hsetKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hsetKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func hsetnxKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hsetnxKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func hgetKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hgetKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func hstrlenKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hstrlenKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func hvalsKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hvalsKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func hrandfieldKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hrandfieldKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 || len(cmd) > 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } if len(cmd) == 2 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func hlenKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hlenKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func hkeysKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hkeysKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func hincrbyKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hincrbyKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func hgetallKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hgetallKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func hexistsKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hexistsKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func hdelKeyFunc(cmd []string) (internal.AccessKeys, error) { +func hdelKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], diff --git a/internal/modules/list/commands.go b/internal/modules/list/commands.go index 448f3415..33f3a6a3 100644 --- a/internal/modules/list/commands.go +++ b/internal/modules/list/commands.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "math" "slices" "strings" @@ -421,7 +421,7 @@ func handleLPush(params internal.HandlerFuncParams) ([]byte, error) { if err = params.SetValue(params.Context, key, append(newElems, l...)); err != nil { return nil, err } - return []byte(constants.OkResponse), nil + return []byte(fmt.Sprintf(":%d\r\n", len(l)+len(newElems))), nil } func handleRPush(params internal.HandlerFuncParams) ([]byte, error) { @@ -469,7 +469,7 @@ func handleRPush(params internal.HandlerFuncParams) ([]byte, error) { if err = params.SetValue(params.Context, key, append(l, newElems...)); err != nil { return nil, err } - return []byte(constants.OkResponse), nil + return []byte(fmt.Sprintf(":%d\r\n", len(l)+len(newElems))), nil } func handlePop(params internal.HandlerFuncParams) ([]byte, error) { diff --git a/internal/modules/list/key_funcs.go b/internal/modules/list/key_funcs.go index 2025d039..7a855e3a 100644 --- a/internal/modules/list/key_funcs.go +++ b/internal/modules/list/key_funcs.go @@ -17,113 +17,113 @@ package list import ( "errors" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" ) -func lpushKeyFunc(cmd []string) (internal.AccessKeys, error) { +func lpushKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func popKeyFunc(cmd []string) (internal.AccessKeys, error) { +func popKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:], }, nil } -func llenKeyFunc(cmd []string) (internal.AccessKeys, error) { +func llenKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func lrangeKeyFunc(cmd []string) (internal.AccessKeys, error) { +func lrangeKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func lindexKeyFunc(cmd []string) (internal.AccessKeys, error) { +func lindexKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func lsetKeyFunc(cmd []string) (internal.AccessKeys, error) { +func lsetKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func ltrimKeyFunc(cmd []string) (internal.AccessKeys, error) { +func ltrimKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func lremKeyFunc(cmd []string) (internal.AccessKeys, error) { +func lremKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func rpushKeyFunc(cmd []string) (internal.AccessKeys, error) { +func rpushKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func lmoveKeyFunc(cmd []string) (internal.AccessKeys, error) { +func lmoveKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 5 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:3], diff --git a/internal/modules/pubsub/commands.go b/internal/modules/pubsub/commands.go index 81a60a3b..eb8e1b27 100644 --- a/internal/modules/pubsub/commands.go +++ b/internal/modules/pubsub/commands.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "strings" ) @@ -108,12 +108,12 @@ func Commands() []internal.Command { Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory}, Description: "(SUBSCRIBE channel [channel ...]) Subscribe to one or more channels.", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { // Treat the channels as keys if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: cmd[1:], ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -127,12 +127,12 @@ func Commands() []internal.Command { Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory}, Description: "(PSUBSCRIBE pattern [pattern ...]) Subscribe to one or more glob patterns.", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { // Treat the patterns as keys if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: cmd[1:], ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -146,12 +146,12 @@ func Commands() []internal.Command { Categories: []string{constants.PubSubCategory, constants.FastCategory}, Description: "(PUBLISH channel message) Publish a message to the specified channel.", Sync: true, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { // Treat the channel as a key if len(cmd) != 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: cmd[1:2], ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -167,9 +167,9 @@ func Commands() []internal.Command { If the channel list is not provided, then the connection will be unsubscribed from all the channels that it's currently subscribe to.`, Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { // Treat the channels as keys - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: cmd[1:], ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -185,8 +185,8 @@ it's currently subscribe to.`, If the pattern list is not provided, then the connection will be unsubscribed from all the patterns that it's currently subscribe to.`, Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: cmd[1:], ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -200,8 +200,8 @@ it's currently subscribe to.`, Categories: []string{}, Description: "", Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -219,8 +219,8 @@ it's currently subscribe to.`, match the given pattern. If no pattern is provided, all active channels are returned. Active channels are channels with 1 or more subscribers.`, Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -234,8 +234,8 @@ channels with 1 or more subscribers.`, Categories: []string{constants.PubSubCategory, constants.SlowCategory}, Description: `(PUBSUB NUMPAT) Return the number of patterns that are currently subscribed to by clients.`, Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), @@ -250,8 +250,8 @@ channels with 1 or more subscribers.`, Description: `(PUBSUB NUMSUB [channel [channel ...]]) Return an array of arrays containing the provided channel name and how many clients are currently subscribed to the channel.`, Sync: false, - KeyExtractionFunc: func(cmd []string) (internal.AccessKeys, error) { - return internal.AccessKeys{ + KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) { + return internal.KeyExtractionFuncResult{ Channels: cmd[2:], ReadKeys: make([]string, 0), WriteKeys: make([]string, 0), diff --git a/internal/modules/set/commands.go b/internal/modules/set/commands.go index fd77af8d..ba19e1f8 100644 --- a/internal/modules/set/commands.go +++ b/internal/modules/set/commands.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "slices" "strings" ) diff --git a/internal/modules/set/key_funcs.go b/internal/modules/set/key_funcs.go index 3e703c48..391f8462 100644 --- a/internal/modules/set/key_funcs.go +++ b/internal/modules/set/key_funcs.go @@ -17,69 +17,69 @@ package set import ( "errors" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "slices" "strings" ) -func saddKeyFunc(cmd []string) (internal.AccessKeys, error) { +func saddKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func scardKeyFunc(cmd []string) (internal.AccessKeys, error) { +func scardKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func sdiffKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sdiffKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func sdiffstoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sdiffstoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:], WriteKeys: cmd[1:2], }, nil } -func sinterKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sinterKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func sintercardKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sintercardKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } limitIdx := slices.IndexFunc(cmd, func(s string) bool { @@ -87,124 +87,124 @@ func sintercardKeyFunc(cmd []string) (internal.AccessKeys, error) { }) if limitIdx == -1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:limitIdx], WriteKeys: make([]string, 0), }, nil } -func sinterstoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sinterstoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:], WriteKeys: cmd[1:2], }, nil } -func sismemberKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sismemberKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func smembersKeyFunc(cmd []string) (internal.AccessKeys, error) { +func smembersKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func smismemberKeyFunc(cmd []string) (internal.AccessKeys, error) { +func smismemberKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func smoveKeyFunc(cmd []string) (internal.AccessKeys, error) { +func smoveKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:3], }, nil } -func spopKeyFunc(cmd []string) (internal.AccessKeys, error) { +func spopKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 || len(cmd) > 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func srandmemberKeyFunc(cmd []string) (internal.AccessKeys, error) { +func srandmemberKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 || len(cmd) > 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func sremKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sremKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func sunionKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sunionKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func sunionstoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func sunionstoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:], WriteKeys: cmd[1:2], diff --git a/internal/modules/sorted_set/commands.go b/internal/modules/sorted_set/commands.go index 5e3fd6e2..9af3d076 100644 --- a/internal/modules/sorted_set/commands.go +++ b/internal/modules/sorted_set/commands.go @@ -19,7 +19,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "math" "slices" "strconv" diff --git a/internal/modules/sorted_set/key_funcs.go b/internal/modules/sorted_set/key_funcs.go index 42e8988e..8c9a5cbf 100644 --- a/internal/modules/sorted_set/key_funcs.go +++ b/internal/modules/sorted_set/key_funcs.go @@ -17,47 +17,47 @@ package sorted_set import ( "errors" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "slices" "strings" ) -func zaddKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zaddKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func zcardKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zcardKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } -func zcountKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zcountKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func zdiffKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zdiffKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } withscoresIndex := slices.IndexFunc(cmd, func(s string) bool { @@ -65,45 +65,45 @@ func zdiffKeyFunc(cmd []string) (internal.AccessKeys, error) { }) if withscoresIndex == -1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:withscoresIndex], WriteKeys: make([]string, 0), }, nil } -func zdiffstoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zdiffstoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:], WriteKeys: cmd[1:2], }, nil } -func zincrbyKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zincrbyKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func zinterKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zinterKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } endIdx := slices.IndexFunc(cmd[1:], func(s string) bool { if strings.EqualFold(s, "WEIGHTS") || @@ -114,25 +114,25 @@ func zinterKeyFunc(cmd []string) (internal.AccessKeys, error) { return false }) if endIdx == -1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } if endIdx >= 1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:endIdx], WriteKeys: make([]string, 0), }, nil } - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } -func zinterstoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zinterstoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } endIdx := slices.IndexFunc(cmd[1:], func(s string) bool { if strings.EqualFold(s, "WEIGHTS") || @@ -143,192 +143,192 @@ func zinterstoreKeyFunc(cmd []string) (internal.AccessKeys, error) { return false }) if endIdx == -1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:], WriteKeys: cmd[1:2], }, nil } if endIdx >= 3 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:endIdx], WriteKeys: cmd[1:2], }, nil } - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } -func zmpopKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zmpopKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } endIdx := slices.IndexFunc(cmd, func(s string) bool { return slices.Contains([]string{"MIN", "MAX", "COUNT"}, strings.ToUpper(s)) }) if endIdx == -1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:], }, nil } if endIdx >= 2 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:endIdx], }, nil } - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } -func zmscoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zmscoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func zpopKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zpopKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 || len(cmd) > 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func zrandmemberKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zrandmemberKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 || len(cmd) > 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func zrankKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zrankKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 || len(cmd) > 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func zremKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zremKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func zrevrankKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zrevrankKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func zscoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zscoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func zremrangebylexKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zremrangebylexKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func zremrangebyrankKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zremrangebyrankKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func zremrangebyscoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zremrangebyscoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func zlexcountKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zlexcountKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func zrangeKeyCount(cmd []string) (internal.AccessKeys, error) { +func zrangeKeyCount(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 4 || len(cmd) > 10 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func zrangeStoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zrangeStoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 5 || len(cmd) > 11 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:3], WriteKeys: cmd[1:2], }, nil } -func zunionKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zunionKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } endIdx := slices.IndexFunc(cmd[1:], func(s string) bool { if strings.EqualFold(s, "WEIGHTS") || @@ -339,25 +339,25 @@ func zunionKeyFunc(cmd []string) (internal.AccessKeys, error) { return false }) if endIdx == -1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:], WriteKeys: make([]string, 0), }, nil } if endIdx >= 1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:endIdx], WriteKeys: cmd[1:endIdx], }, nil } - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } -func zunionstoreKeyFunc(cmd []string) (internal.AccessKeys, error) { +func zunionstoreKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) < 3 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } endIdx := slices.IndexFunc(cmd[1:], func(s string) bool { if strings.EqualFold(s, "WEIGHTS") || @@ -368,18 +368,18 @@ func zunionstoreKeyFunc(cmd []string) (internal.AccessKeys, error) { return false }) if endIdx == -1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:], WriteKeys: cmd[1:2], }, nil } if endIdx >= 1 { - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[2:endIdx], WriteKeys: cmd[1:2], }, nil } - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } diff --git a/internal/modules/string/commands.go b/internal/modules/string/commands.go index ce3ce904..b4662282 100644 --- a/internal/modules/string/commands.go +++ b/internal/modules/string/commands.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" ) func handleSetRange(params internal.HandlerFuncParams) ([]byte, error) { diff --git a/internal/modules/string/key_funcs.go b/internal/modules/string/key_funcs.go index 95ee5b5f..960e784e 100644 --- a/internal/modules/string/key_funcs.go +++ b/internal/modules/string/key_funcs.go @@ -17,36 +17,36 @@ package str import ( "errors" "github.com/echovault/echovault/internal" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" ) -func setRangeKeyFunc(cmd []string) (internal.AccessKeys, error) { +func setRangeKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: make([]string, 0), WriteKeys: cmd[1:2], }, nil } -func strLenKeyFunc(cmd []string) (internal.AccessKeys, error) { +func strLenKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 2 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), }, nil } -func subStrKeyFunc(cmd []string) (internal.AccessKeys, error) { +func subStrKeyFunc(cmd []string) (internal.KeyExtractionFuncResult, error) { if len(cmd) != 4 { - return internal.AccessKeys{}, errors.New(constants.WrongArgsResponse) + return internal.KeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) } - return internal.AccessKeys{ + return internal.KeyExtractionFuncResult{ Channels: make([]string, 0), ReadKeys: cmd[1:2], WriteKeys: make([]string, 0), diff --git a/internal/raft/fsm.go b/internal/raft/fsm.go index 8f7aa2e9..c70407dd 100644 --- a/internal/raft/fsm.go +++ b/internal/raft/fsm.go @@ -20,19 +20,22 @@ import ( "fmt" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/types" "github.com/hashicorp/raft" "io" "log" "net" "strings" + "time" ) type FSMOpts struct { Config config.Config - EchoVault types.EchoVault GetState func() map[string]internal.KeyData GetCommand func(command string) (internal.Command, error) + CreateKeyAndLock func(ctx context.Context, key string) (bool, error) + SetValue func(ctx context.Context, key string, value interface{}) error + SetExpiry func(ctx context.Context, key string, expire time.Time, touch bool) + KeyUnlock func(ctx context.Context, key string) DeleteKey func(ctx context.Context, key string) error StartSnapshot func() FinishSnapshot func() @@ -99,7 +102,14 @@ func (fsm *FSM) Apply(log *raft.Log) interface{} { handler := command.HandlerFunc - subCommand, ok := internal.GetSubCommand(command, request.CMD).(internal.SubCommand) + sc, err := internal.GetSubCommand(command, request.CMD) + if err != nil { + return internal.ApplyResponse{ + Error: err, + Response: nil, + } + } + subCommand, ok := sc.(internal.SubCommand) if ok { handler = subCommand.HandlerFunc } @@ -154,14 +164,14 @@ func (fsm *FSM) Restore(snapshot io.ReadCloser) error { // Set state ctx := context.Background() for k, v := range internal.FilterExpiredKeys(data.State) { - if _, err = fsm.options.EchoVault.CreateKeyAndLock(ctx, k); err != nil { + if _, err = fsm.options.CreateKeyAndLock(ctx, k); err != nil { log.Fatal(err) } - if err = fsm.options.EchoVault.SetValue(ctx, k, v.Value); err != nil { + if err = fsm.options.SetValue(ctx, k, v.Value); err != nil { log.Fatal(err) } - fsm.options.EchoVault.SetExpiry(ctx, k, v.ExpireAt, false) - fsm.options.EchoVault.KeyUnlock(ctx, k) + fsm.options.SetExpiry(ctx, k, v.ExpireAt, false) + fsm.options.KeyUnlock(ctx, k) } // Set latest snapshot milliseconds fsm.options.SetLatestSnapshotTime(data.LatestSnapshotMilliseconds) diff --git a/internal/raft/raft.go b/internal/raft/raft.go index f74532ac..29ca20d7 100644 --- a/internal/raft/raft.go +++ b/internal/raft/raft.go @@ -27,7 +27,7 @@ import ( "path/filepath" "time" - "github.com/echovault/echovault/pkg/types" + "github.com/echovault/echovault/types" "github.com/hashicorp/raft" raftboltdb "github.com/hashicorp/raft-boltdb" ) @@ -35,6 +35,10 @@ import ( type Opts struct { Config config.Config EchoVault types.EchoVault + CreateKeyAndLock func(ctx context.Context, key string) (bool, error) + SetValue func(ctx context.Context, key string, value interface{}) error + SetExpiry func(ctx context.Context, key string, expire time.Time, touch bool) + KeyUnlock func(ctx context.Context, key string) GetState func() map[string]internal.KeyData GetCommand func(command string) (internal.Command, error) DeleteKey func(ctx context.Context, key string) error @@ -114,9 +118,12 @@ func (r *Raft) RaftInit(ctx context.Context) { raftConfig, NewFSM(FSMOpts{ Config: r.options.Config, - EchoVault: r.options.EchoVault, GetState: r.options.GetState, GetCommand: r.options.GetCommand, + CreateKeyAndLock: r.options.CreateKeyAndLock, + SetValue: r.options.SetValue, + SetExpiry: r.options.SetExpiry, + KeyUnlock: r.options.KeyUnlock, DeleteKey: r.options.DeleteKey, StartSnapshot: r.options.StartSnapshot, FinishSnapshot: r.options.FinishSnapshot, diff --git a/internal/types.go b/internal/types.go index 56990e28..56958cc4 100644 --- a/internal/types.go +++ b/internal/types.go @@ -47,13 +47,13 @@ type SnapshotObject struct { LatestSnapshotMilliseconds int64 } -type AccessKeys struct { +type KeyExtractionFuncResult struct { Channels []string ReadKeys []string WriteKeys []string } -type KeyExtractionFunc func(cmd []string) (AccessKeys, error) +type KeyExtractionFunc func(cmd []string) (KeyExtractionFuncResult, error) type HandlerFuncParams struct { Context context.Context diff --git a/internal/utils.go b/internal/utils.go index f27b0155..e7ef6081 100644 --- a/internal/utils.go +++ b/internal/utils.go @@ -20,7 +20,7 @@ import ( "cmp" "errors" "fmt" - "github.com/echovault/echovault/pkg/constants" + "github.com/echovault/echovault/internal/constants" "io" "log" "math/big" @@ -128,16 +128,21 @@ func GetIPAddress() (string, error) { return localAddr, nil } -func GetSubCommand(command Command, cmd []string) interface{} { - if len(command.SubCommands) == 0 || len(cmd) < 2 { - return nil +func GetSubCommand(command Command, cmd []string) (interface{}, error) { + if command.SubCommands == nil || len(command.SubCommands) == 0 { + // If the command has no sub-commands, return nil + return nil, nil + } + if len(cmd) < 2 { + // If the cmd provided by the user has less than 2 tokens, there's no need to search for a subcommand + return nil, nil } for _, subCommand := range command.SubCommands { if strings.EqualFold(subCommand.Command, cmd[1]) { - return subCommand + return subCommand, nil } } - return nil + return nil, fmt.Errorf("command %s %s not supported", cmd[0], cmd[1]) } func IsWriteCommand(command Command, subCommand SubCommand) bool { diff --git a/pkg/echovault/api_admin.go b/pkg/echovault/api_admin.go deleted file mode 100644 index 8e248bfe..00000000 --- a/pkg/echovault/api_admin.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2024 Kelvin Clement Mwinuka -// -// Licensed under the Apache License, Version 2.0 (the "License");s -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package echovault - -import "github.com/echovault/echovault/internal" - -// CommandListOptions modifies the result from the COMMAND_LIST command. -// -// ACLCAT filters the results by the provided category. Has the highest priority. -// -// PATTERN filters the result that match the given glob pattern. Has the second-highest priority. -// -// MODULE filters the result by the provided module. Has the lowest priority. -type CommandListOptions struct { - ACLCAT string - PATTERN string - MODULE string -} - -// COMMAND_LIST returns the list of commands currently loaded in the EchoVault instance. -// -// Parameters: -// -// `options` - CommandListOptions. -// -// Returns: a string slice of all the loaded commands. SubCommands are represented as "command|subcommand". -func (server *EchoVault) COMMAND_LIST(options CommandListOptions) ([]string, error) { - cmd := []string{"COMMAND", "LIST"} - - switch { - case options.ACLCAT != "": - cmd = append(cmd, []string{"FILTERBY", "ACLCAT", options.ACLCAT}...) - case options.PATTERN != "": - cmd = append(cmd, []string{"FILTERBY", "PATTERN", options.PATTERN}...) - case options.MODULE != "": - cmd = append(cmd, []string{"FILTERBY", "MODULE", options.MODULE}...) - } - - b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) - if err != nil { - return nil, err - } - - return internal.ParseStringArrayResponse(b) -} - -// COMMAND_COUNT returns the number of commands currently loaded in the EchoVault instance. -// -// Returns: integer representing the count of all available commands. -func (server *EchoVault) COMMAND_COUNT() (int, error) { - b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"COMMAND", "COUNT"}), nil, false, true) - if err != nil { - return 0, err - } - return internal.ParseIntegerResponse(b) -} - -// SAVE triggers a new snapshot. -func (server *EchoVault) SAVE() (string, error) { - b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"SAVE"}), nil, false, true) - if err != nil { - return "", err - } - return internal.ParseStringResponse(b) -} - -// LASTSAVE returns the unix epoch milliseconds timestamp of the last save. -func (server *EchoVault) LASTSAVE() (int, error) { - b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"LASTSAVE"}), nil, false, true) - if err != nil { - return 0, err - } - return internal.ParseIntegerResponse(b) -} - -// REWRITEAOF triggers a compaction of the AOF file. -func (server *EchoVault) REWRITEAOF() (string, error) { - b, err := server.handleCommand(server.context, internal.EncodeCommand([]string{"REWRITEAOF"}), nil, false, true) - if err != nil { - return "", err - } - return internal.ParseStringResponse(b) -} diff --git a/pkg/types/types.go b/pkg/types/types.go deleted file mode 100644 index 2b4f46cc..00000000 --- a/pkg/types/types.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2024 Kelvin Clement Mwinuka -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - "context" - "time" -) - -type EchoVault interface { - KeyLock(ctx context.Context, key string) (bool, error) - KeyUnlock(ctx context.Context, key string) - KeyRLock(ctx context.Context, key string) (bool, error) - KeyRUnlock(ctx context.Context, key string) - KeyExists(ctx context.Context, key string) bool - CreateKeyAndLock(ctx context.Context, key string) (bool, error) - GetValue(ctx context.Context, key string) interface{} - SetValue(ctx context.Context, key string, value interface{}) error - GetExpiry(ctx context.Context, key string) time.Time - SetExpiry(ctx context.Context, key string, expire time.Time, touch bool) - RemoveExpiry(ctx context.Context, key string) - DeleteKey(ctx context.Context, key string) error -} diff --git a/test/modules/acl/commands_test.go b/test/modules/acl/commands_test.go index bbc2b3ed..bb0d9b82 100644 --- a/test/modules/acl/commands_test.go +++ b/test/modules/acl/commands_test.go @@ -17,10 +17,10 @@ package acl import ( "crypto/sha256" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal/config" + "github.com/echovault/echovault/internal/constants" "github.com/echovault/echovault/internal/modules/acl" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" "github.com/tidwall/resp" "net" "reflect" diff --git a/test/modules/admin/api_test.go b/test/modules/admin/api_test.go index d643816b..1eabe9ad 100644 --- a/test/modules/admin/api_test.go +++ b/test/modules/admin/api_test.go @@ -13,3 +13,297 @@ // limitations under the License. package admin + +import ( + "bytes" + "errors" + "fmt" + "github.com/echovault/echovault/echovault" + "github.com/echovault/echovault/internal/config" + "github.com/echovault/echovault/internal/constants" + "github.com/echovault/echovault/types" + "github.com/tidwall/resp" + "strconv" + "testing" +) + +func createEchoVault() *echovault.EchoVault { + ev, _ := echovault.NewEchoVault( + echovault.WithConfig(config.Config{ + DataDir: "", + }), + ) + return ev +} + +func TestEchoVault_AddCommand(t *testing.T) { + type args struct { + command echovault.CommandOptions + } + type scenarios struct { + name string + command []string + wantRes int + wantErr error + } + tests := []struct { + name string + args args + scenarios []scenarios + wantErr bool + }{ + { + name: "1 Add command without subcommands", + wantErr: false, + args: args{ + command: echovault.CommandOptions{ + Command: "CommandOne", + Module: "test-module", + Description: `(CommandOne write-key read-key ) +Test command to handle successful addition of a single command without subcommands. +The value passed must be an integer.`, + Categories: []string{}, + Sync: false, + KeyExtractionFunc: func(cmd []string) (types.CommandKeyExtractionFuncResult, error) { + if len(cmd) != 4 { + return types.CommandKeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) + } + return types.CommandKeyExtractionFuncResult{ + WriteKeys: cmd[1:2], + ReadKeys: cmd[2:3], + }, nil + }, + HandlerFunc: func(params types.CommandHandlerFuncParams) ([]byte, error) { + if len(params.Command) != 4 { + return nil, errors.New(constants.WrongArgsResponse) + } + value := params.Command[3] + i, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return nil, errors.New("value must be an integer") + } + return []byte(fmt.Sprintf(":%d\r\n", i)), nil + }, + }, + }, + scenarios: []scenarios{ + { + name: "1 Successfully execute the command and return the expected integer.", + command: []string{"CommandOne", "write-key1", "read-key1", "1111"}, + wantRes: 1111, + wantErr: nil, + }, + { + name: "2 Get error due to command being too long", + command: []string{"CommandOne", "write-key1", "read-key1", "1111", "2222"}, + wantRes: 0, + wantErr: errors.New(constants.WrongArgsResponse), + }, + { + name: "3 Get error due to command being too short", + command: []string{"CommandOne", "write-key1", "read-key1"}, + wantRes: 0, + wantErr: errors.New(constants.WrongArgsResponse), + }, + { + name: "4 Get error due to value not being an integer", + command: []string{"CommandOne", "write-key1", "read-key1", "string"}, + wantRes: 0, + wantErr: errors.New("value must be an integer"), + }, + }, + }, + { + name: "2 Add command with subcommands", + wantErr: false, + args: args{ + command: echovault.CommandOptions{ + Command: "CommandTwo", + SubCommand: []echovault.SubCommandOptions{ + { + Command: "SubCommandOne", + Module: "test-module", + Description: `(CommandTwo SubCommandOne write-key read-key ) +Test command to handle successful addition of a single command with subcommands. +The value passed must be an integer.`, + Categories: []string{}, + Sync: false, + KeyExtractionFunc: func(cmd []string) (types.CommandKeyExtractionFuncResult, error) { + if len(cmd) != 5 { + return types.CommandKeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse) + } + return types.CommandKeyExtractionFuncResult{ + WriteKeys: cmd[2:3], + ReadKeys: cmd[3:4], + }, nil + }, + HandlerFunc: func(params types.CommandHandlerFuncParams) ([]byte, error) { + if len(params.Command) != 5 { + return nil, errors.New(constants.WrongArgsResponse) + } + value := params.Command[4] + i, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return nil, errors.New("value must be an integer") + } + return []byte(fmt.Sprintf(":%d\r\n", i)), nil + }, + }, + }, + }, + }, + scenarios: []scenarios{ + { + name: "1 Successfully execute the command and return the expected integer.", + command: []string{"CommandTwo", "SubCommandOne", "write-key1", "read-key1", "1111"}, + wantRes: 1111, + wantErr: nil, + }, + { + name: "2 Get error due to command being too long", + command: []string{"CommandTwo", "SubCommandOne", "write-key1", "read-key1", "1111", "2222"}, + wantRes: 0, + wantErr: errors.New(constants.WrongArgsResponse), + }, + { + name: "3 Get error due to command being too short", + command: []string{"CommandTwo", "SubCommandOne", "write-key1", "read-key1"}, + wantRes: 0, + wantErr: errors.New(constants.WrongArgsResponse), + }, + { + name: "4 Get error due to value not being an integer", + command: []string{"CommandTwo", "SubCommandOne", "write-key1", "read-key1", "string"}, + wantRes: 0, + wantErr: errors.New("value must be an integer"), + }, + }, + }, + } + for _, tt := range tests { + server := createEchoVault() + t.Run(tt.name, func(t *testing.T) { + if err := server.AddCommand(tt.args.command); (err != nil) != tt.wantErr { + t.Errorf("AddCommand() error = %v, wantErr %v", err, tt.wantErr) + } + for _, scenario := range tt.scenarios { + b, err := server.ExecuteCommand(scenario.command...) + if scenario.wantErr != nil { + if scenario.wantErr.Error() != err.Error() { + t.Errorf("AddCommand() error = %v, wantErr %v", err, scenario.wantErr) + } + continue + } + r := resp.NewReader(bytes.NewReader(b)) + v, _, _ := r.ReadValue() + if v.Integer() != scenario.wantRes { + t.Errorf("AddCommand() res = %v, wantRes %v", resp.BytesValue(b).Integer(), scenario.wantRes) + } + } + }) + } +} + +func TestEchoVault_ExecuteCommand(t *testing.T) { + type args struct { + key string + presetValue []string + command []string + } + tests := []struct { + name string + args args + wantRes int + wantErr error + }{ + { + name: "1 Execute LPUSH command and get expected result", + args: args{ + key: "key1", + presetValue: []string{"1", "2", "3"}, + command: []string{"LPUSH", "key1", "4", "5", "6", "7", "8", "9", "10"}, + }, + wantRes: 10, + wantErr: nil, + }, + { + name: "2 Expect error when trying to execute non-existent command", + args: args{ + key: "key2", + presetValue: nil, + command: []string{"NON-EXISTENT", "key1", "key2"}, + }, + wantRes: 0, + wantErr: errors.New("command NON-EXISTENT not supported"), + }, + } + for _, tt := range tests { + server := createEchoVault() + t.Run(tt.name, func(t *testing.T) { + if tt.args.presetValue != nil { + _, _ = server.LPush(tt.args.key, tt.args.presetValue...) + } + b, err := server.ExecuteCommand(tt.args.command...) + if tt.wantErr != nil { + if err.Error() != tt.wantErr.Error() { + t.Errorf("ExecuteCommand() error = %v, wantErr %v", err, tt.wantErr) + } + } + r := resp.NewReader(bytes.NewReader(b)) + v, _, _ := r.ReadValue() + if v.Integer() != tt.wantRes { + fmt.Println("RES: ", string(b)) + t.Errorf("ExecuteCommand() response = %d, wantRes %d", v.Integer(), tt.wantRes) + } + }) + } +} + +func TestEchoVault_RemoveCommand(t *testing.T) { + type args struct { + removeCommand []string + executeCommand []string + } + tests := []struct { + name string + args args + wantErr error + }{ + { + name: "1 Remove command and expect error when the command is called", + args: args{ + removeCommand: []string{"LPUSH"}, + executeCommand: []string{"LPUSH", "key", "item"}, + }, + wantErr: errors.New("command LPUSH not supported"), + }, + { + name: "2 Remove sub-command and expect error when the subcommand is called", + args: args{ + removeCommand: []string{"ACL", "CAT"}, + executeCommand: []string{"ACL", "CAT"}, + }, + wantErr: errors.New("command ACL CAT not supported"), + }, + { + name: "3 Remove sub-command and expect successful response from calling another subcommand", + args: args{ + removeCommand: []string{"ACL", "WHOAMI"}, + executeCommand: []string{"ACL", "DELUSER", "user-one"}, + }, + wantErr: nil, + }, + } + for _, tt := range tests { + server := createEchoVault() + t.Run(tt.name, func(t *testing.T) { + server.RemoveCommand(tt.args.removeCommand...) + _, err := server.ExecuteCommand(tt.args.executeCommand...) + if tt.wantErr != nil { + if err.Error() != tt.wantErr.Error() { + t.Errorf("RemoveCommand() error = %v, wantErr %v", err, tt.wantErr) + } + } + }) + } +} diff --git a/test/modules/admin/commands_test.go b/test/modules/admin/commands_test.go index fd6ea317..c4e932cc 100644 --- a/test/modules/admin/commands_test.go +++ b/test/modules/admin/commands_test.go @@ -18,10 +18,10 @@ import ( "bytes" "context" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" + "github.com/echovault/echovault/internal/constants" "github.com/tidwall/resp" "net" "reflect" diff --git a/test/modules/connection/commands_test.go b/test/modules/connection/commands_test.go index 6e3a05b6..8d1e08fc 100644 --- a/test/modules/connection/commands_test.go +++ b/test/modules/connection/commands_test.go @@ -18,10 +18,10 @@ import ( "bytes" "context" "errors" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" + "github.com/echovault/echovault/internal/constants" "github.com/tidwall/resp" "net" "reflect" diff --git a/test/modules/generic/api_test.go b/test/modules/generic/api_test.go index b18281b9..b7760fb8 100644 --- a/test/modules/generic/api_test.go +++ b/test/modules/generic/api_test.go @@ -16,10 +16,10 @@ package generic import ( "context" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/clock" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/echovault" "reflect" "slices" "strings" @@ -84,7 +84,7 @@ func TestEchoVault_DEL(t *testing.T) { presetKeyData(server, context.Background(), k, d) } } - got, err := server.DEL(tt.keys...) + got, err := server.Del(tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("DEL() error = %v, wantErr %v", err, tt.wantErr) return @@ -107,8 +107,8 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd string key string time int - expireOpts echovault.EXPIREOptions - pexpireOpts echovault.PEXPIREOptions + expireOpts echovault.ExpireOptions + pexpireOpts echovault.PExpireOptions want int wantErr bool }{ @@ -117,7 +117,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key1", time: 100, - expireOpts: echovault.EXPIREOptions{}, + expireOpts: echovault.ExpireOptions{}, presetValues: map[string]internal.KeyData{ "key1": {Value: "value1", ExpireAt: time.Time{}}, }, @@ -129,7 +129,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "PEXPIRE", key: "key2", time: 1000, - pexpireOpts: echovault.PEXPIREOptions{}, + pexpireOpts: echovault.PExpireOptions{}, presetValues: map[string]internal.KeyData{ "key2": {Value: "value2", ExpireAt: time.Time{}}, }, @@ -141,7 +141,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key3", time: 1000, - expireOpts: echovault.EXPIREOptions{NX: true}, + expireOpts: echovault.ExpireOptions{NX: true}, presetValues: map[string]internal.KeyData{ "key3": {Value: "value3", ExpireAt: time.Time{}}, }, @@ -153,7 +153,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key4", time: 1000, - expireOpts: echovault.EXPIREOptions{NX: true}, + expireOpts: echovault.ExpireOptions{NX: true}, presetValues: map[string]internal.KeyData{ "key4": {Value: "value4", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, @@ -165,7 +165,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key5", time: 1000, - expireOpts: echovault.EXPIREOptions{XX: true}, + expireOpts: echovault.ExpireOptions{XX: true}, presetValues: map[string]internal.KeyData{ "key5": {Value: "value5", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, @@ -176,7 +176,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { name: "Return 0 when key does not have an expiry and the XX flag is provided", cmd: "EXPIRE", time: 1000, - expireOpts: echovault.EXPIREOptions{XX: true}, + expireOpts: echovault.ExpireOptions{XX: true}, key: "key6", presetValues: map[string]internal.KeyData{ "key6": {Value: "value6", ExpireAt: time.Time{}}, @@ -189,7 +189,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key7", time: 100000, - expireOpts: echovault.EXPIREOptions{GT: true}, + expireOpts: echovault.ExpireOptions{GT: true}, presetValues: map[string]internal.KeyData{ "key7": {Value: "value7", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, @@ -201,7 +201,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key8", time: 1000, - expireOpts: echovault.EXPIREOptions{GT: true}, + expireOpts: echovault.ExpireOptions{GT: true}, presetValues: map[string]internal.KeyData{ "key8": {Value: "value8", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, @@ -213,7 +213,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key9", time: 1000, - expireOpts: echovault.EXPIREOptions{GT: true}, + expireOpts: echovault.ExpireOptions{GT: true}, presetValues: map[string]internal.KeyData{ "key9": {Value: "value9", ExpireAt: time.Time{}}, }, @@ -225,7 +225,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key10", time: 1000, - expireOpts: echovault.EXPIREOptions{LT: true}, + expireOpts: echovault.ExpireOptions{LT: true}, presetValues: map[string]internal.KeyData{ "key10": {Value: "value10", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, @@ -237,7 +237,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { cmd: "EXPIRE", key: "key11", time: 50000, - expireOpts: echovault.EXPIREOptions{LT: true}, + expireOpts: echovault.ExpireOptions{LT: true}, presetValues: map[string]internal.KeyData{ "key11": {Value: "value11", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, @@ -255,9 +255,9 @@ func TestEchoVault_EXPIRE(t *testing.T) { var got int var err error if strings.EqualFold(tt.cmd, "PEXPIRE") { - got, err = server.PEXPIRE(tt.key, tt.time, tt.pexpireOpts) + got, err = server.PExpire(tt.key, tt.time, tt.pexpireOpts) } else { - got, err = server.EXPIRE(tt.key, tt.time, tt.expireOpts) + got, err = server.Expire(tt.key, tt.time, tt.expireOpts) } if (err != nil) != tt.wantErr { t.Errorf("(P)EXPIRE() error = %v, wantErr %v, key %s", err, tt.wantErr, tt.key) @@ -281,8 +281,8 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd string key string time int - expireAtOpts echovault.EXPIREATOptions - pexpireAtOpts echovault.PEXPIREATOptions + expireAtOpts echovault.ExpireAtOptions + pexpireAtOpts echovault.PExpireAtOptions want int wantErr bool }{ @@ -290,7 +290,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Set new expire by unix seconds", cmd: "EXPIREAT", key: "key1", - expireAtOpts: echovault.EXPIREATOptions{}, + expireAtOpts: echovault.ExpireAtOptions{}, time: int(mockClock.Now().Add(1000 * time.Second).Unix()), presetValues: map[string]internal.KeyData{ "key1": {Value: "value1", ExpireAt: time.Time{}}, @@ -302,7 +302,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Set new expire by milliseconds", cmd: "PEXPIREAT", key: "key2", - pexpireAtOpts: echovault.PEXPIREATOptions{}, + pexpireAtOpts: echovault.PExpireAtOptions{}, time: int(mockClock.Now().Add(1000 * time.Second).UnixMilli()), presetValues: map[string]internal.KeyData{ "key2": {Value: "value2", ExpireAt: time.Time{}}, @@ -315,7 +315,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key3", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{NX: true}, + expireAtOpts: echovault.ExpireAtOptions{NX: true}, presetValues: map[string]internal.KeyData{ "key3": {Value: "value3", ExpireAt: time.Time{}}, }, @@ -326,7 +326,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Return 0, when NX flag is provided and key already has an expiry time", cmd: "EXPIREAT", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{NX: true}, + expireAtOpts: echovault.ExpireAtOptions{NX: true}, key: "key4", presetValues: map[string]internal.KeyData{ "key4": {Value: "value4", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, @@ -339,7 +339,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), key: "key5", - expireAtOpts: echovault.EXPIREATOptions{XX: true}, + expireAtOpts: echovault.ExpireAtOptions{XX: true}, presetValues: map[string]internal.KeyData{ "key5": {Value: "value5", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, @@ -351,7 +351,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key6", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{XX: true}, + expireAtOpts: echovault.ExpireAtOptions{XX: true}, presetValues: map[string]internal.KeyData{ "key6": {Value: "value6", ExpireAt: time.Time{}}, }, @@ -363,7 +363,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key7", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{GT: true}, + expireAtOpts: echovault.ExpireAtOptions{GT: true}, presetValues: map[string]internal.KeyData{ "key7": {Value: "value7", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, @@ -375,7 +375,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key8", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{GT: true}, + expireAtOpts: echovault.ExpireAtOptions{GT: true}, presetValues: map[string]internal.KeyData{ "key8": {Value: "value8", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, @@ -387,7 +387,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key9", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{GT: true}, + expireAtOpts: echovault.ExpireAtOptions{GT: true}, presetValues: map[string]internal.KeyData{ "key9": {Value: "value9", ExpireAt: time.Time{}}, }, @@ -398,7 +398,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key10", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{LT: true}, + expireAtOpts: echovault.ExpireAtOptions{LT: true}, presetValues: map[string]internal.KeyData{ "key10": {Value: "value10", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, @@ -410,7 +410,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key11", time: int(mockClock.Now().Add(3000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{LT: true}, + expireAtOpts: echovault.ExpireAtOptions{LT: true}, presetValues: map[string]internal.KeyData{ "key11": {Value: "value11", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, @@ -422,7 +422,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key12", time: int(mockClock.Now().Add(1000 * time.Second).Unix()), - expireAtOpts: echovault.EXPIREATOptions{LT: true}, + expireAtOpts: echovault.ExpireAtOptions{LT: true}, presetValues: map[string]internal.KeyData{ "key12": {Value: "value12", ExpireAt: time.Time{}}, }, @@ -440,9 +440,9 @@ func TestEchoVault_EXPIREAT(t *testing.T) { var got int var err error if strings.EqualFold(tt.cmd, "PEXPIREAT") { - got, err = server.PEXPIREAT(tt.key, tt.time, tt.pexpireAtOpts) + got, err = server.PExpireAt(tt.key, tt.time, tt.pexpireAtOpts) } else { - got, err = server.EXPIREAT(tt.key, tt.time, tt.expireAtOpts) + got, err = server.ExpireAt(tt.key, tt.time, tt.expireAtOpts) } if (err != nil) != tt.wantErr { t.Errorf("(P)EXPIREAT() error = %v, wantErr %v, KEY %s", err, tt.wantErr, tt.key) @@ -474,7 +474,7 @@ func TestEchoVault_EXPIRETIME(t *testing.T) { presetValues: map[string]internal.KeyData{ "key1": {Value: "value1", ExpireAt: mockClock.Now().Add(100 * time.Second)}, }, - expiretimeFunc: server.EXPIRETIME, + expiretimeFunc: server.ExpireTime, want: int(mockClock.Now().Add(100 * time.Second).Unix()), wantErr: false, }, @@ -484,7 +484,7 @@ func TestEchoVault_EXPIRETIME(t *testing.T) { presetValues: map[string]internal.KeyData{ "key2": {Value: "value2", ExpireAt: mockClock.Now().Add(4096 * time.Millisecond)}, }, - expiretimeFunc: server.PEXPIRETIME, + expiretimeFunc: server.PExpireTime, want: int(mockClock.Now().Add(4096 * time.Millisecond).UnixMilli()), wantErr: false, }, @@ -494,14 +494,14 @@ func TestEchoVault_EXPIRETIME(t *testing.T) { presetValues: map[string]internal.KeyData{ "key3": {Value: "value3", ExpireAt: time.Time{}}, }, - expiretimeFunc: server.PEXPIRETIME, + expiretimeFunc: server.PExpireTime, want: -1, wantErr: false, }, { name: "If the key is non-existent return -2", presetValues: nil, - expiretimeFunc: server.PEXPIRETIME, + expiretimeFunc: server.PExpireTime, want: -2, wantErr: false, }, @@ -559,7 +559,7 @@ func TestEchoVault_GET(t *testing.T) { return } } - got, err := server.GET(tt.key) + got, err := server.Get(tt.key) if (err != nil) != tt.wantErr { t.Errorf("GET() error = %v, wantErr %v", err, tt.wantErr) return @@ -607,7 +607,7 @@ func TestEchoVault_MGET(t *testing.T) { } } } - got, err := server.MGET(tt.keys...) + got, err := server.MGet(tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("MGET() error = %v, wantErr %v", err, tt.wantErr) return @@ -637,7 +637,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues map[string]internal.KeyData key string value string - options echovault.SETOptions + options echovault.SetOptions want string wantErr bool }{ @@ -646,7 +646,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues: nil, key: "key1", value: "value1", - options: echovault.SETOptions{}, + options: echovault.SetOptions{}, want: "OK", wantErr: false, }, @@ -655,7 +655,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues: nil, key: "key2", value: "value2", - options: echovault.SETOptions{NX: true}, + options: echovault.SetOptions{NX: true}, want: "OK", wantErr: false, }, @@ -669,7 +669,7 @@ func TestEchoVault_SET(t *testing.T) { }, key: "key3", value: "value3", - options: echovault.SETOptions{NX: true}, + options: echovault.SetOptions{NX: true}, want: "", wantErr: true, }, @@ -683,7 +683,7 @@ func TestEchoVault_SET(t *testing.T) { }, key: "key4", value: "value4", - options: echovault.SETOptions{XX: true}, + options: echovault.SetOptions{XX: true}, want: "OK", wantErr: false, }, @@ -692,7 +692,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues: nil, key: "key5", value: "value5", - options: echovault.SETOptions{XX: true}, + options: echovault.SetOptions{XX: true}, want: "", wantErr: true, }, @@ -701,7 +701,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues: nil, key: "key6", value: "value6", - options: echovault.SETOptions{EX: 100}, + options: echovault.SetOptions{EX: 100}, want: "OK", wantErr: false, }, @@ -710,7 +710,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues: nil, key: "key7", value: "value7", - options: echovault.SETOptions{PX: 4096}, + options: echovault.SetOptions{PX: 4096}, want: "OK", wantErr: false, }, @@ -719,7 +719,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues: nil, key: "key8", value: "value8", - options: echovault.SETOptions{EXAT: int(mockClock.Now().Add(200 * time.Second).Unix())}, + options: echovault.SetOptions{EXAT: int(mockClock.Now().Add(200 * time.Second).Unix())}, want: "OK", wantErr: false, }, @@ -727,7 +727,7 @@ func TestEchoVault_SET(t *testing.T) { name: "Set exact expiry time in milliseconds from unix epoch", key: "key9", value: "value9", - options: echovault.SETOptions{PXAT: int(mockClock.Now().Add(4096 * time.Millisecond).UnixMilli())}, + options: echovault.SetOptions{PXAT: int(mockClock.Now().Add(4096 * time.Millisecond).UnixMilli())}, presetValues: nil, want: "OK", wantErr: false, @@ -742,7 +742,7 @@ func TestEchoVault_SET(t *testing.T) { }, key: "key10", value: "value10", - options: echovault.SETOptions{GET: true, EX: 1000}, + options: echovault.SetOptions{GET: true, EX: 1000}, want: "previous-value", wantErr: false, }, @@ -751,7 +751,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues: nil, key: "key11", value: "value11", - options: echovault.SETOptions{GET: true, EX: 1000}, + options: echovault.SetOptions{GET: true, EX: 1000}, want: "", wantErr: false, }, @@ -763,7 +763,7 @@ func TestEchoVault_SET(t *testing.T) { presetKeyData(server, context.Background(), k, d) } } - got, err := server.SET(tt.key, tt.value, tt.options) + got, err := server.Set(tt.key, tt.value, tt.options) if (err != nil) != tt.wantErr { t.Errorf("SET() error = %v, wantErr %v", err, tt.wantErr) return @@ -793,7 +793,7 @@ func TestEchoVault_MSET(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := server.MSET(tt.kvPairs) + got, err := server.MSet(tt.kvPairs) if (err != nil) != tt.wantErr { t.Errorf("MSET() error = %v, wantErr %v", err, tt.wantErr) return @@ -850,7 +850,7 @@ func TestEchoVault_PERSIST(t *testing.T) { presetKeyData(server, context.Background(), k, d) } } - got, err := server.PERSIST(tt.key) + got, err := server.Persist(tt.key) if (err != nil) != tt.wantErr { t.Errorf("PERSIST() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/test/modules/generic/commands_test.go b/test/modules/generic/commands_test.go index 9598de09..d73df9c4 100644 --- a/test/modules/generic/commands_test.go +++ b/test/modules/generic/commands_test.go @@ -19,11 +19,11 @@ import ( "context" "errors" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/clock" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" + "github.com/echovault/echovault/internal/constants" "github.com/tidwall/resp" "net" "reflect" @@ -599,7 +599,7 @@ func Test_HandleGET(t *testing.T) { value: "3.142", }, } - // Test successful GET command + // Test successful Get command for i, test := range tests { t.Run(test.name, func(t *testing.T) { ctx := context.WithValue(context.Background(), "test_name", fmt.Sprintf("GET, %d", i)) diff --git a/test/modules/hash/api_test.go b/test/modules/hash/api_test.go index 6ef4db5e..2abbd7b7 100644 --- a/test/modules/hash/api_test.go +++ b/test/modules/hash/api_test.go @@ -16,8 +16,8 @@ package hash import ( "context" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/echovault" "reflect" "slices" "testing" @@ -96,7 +96,7 @@ func TestEchoVault_HDEL(t *testing.T) { return } } - got, err := server.HDEL(tt.key, tt.fields...) + got, err := server.HDel(tt.key, tt.fields...) if (err != nil) != tt.wantErr { t.Errorf("HDEL() error = %v, wantErr %v", err, tt.wantErr) return @@ -153,7 +153,7 @@ func TestEchoVault_HEXISTS(t *testing.T) { return } } - got, err := server.HEXISTS(tt.key, tt.field) + got, err := server.HExists(tt.key, tt.field) if (err != nil) != tt.wantErr { t.Errorf("HEXISTS() error = %v, wantErr %v", err, tt.wantErr) return @@ -206,7 +206,7 @@ func TestEchoVault_HGETALL(t *testing.T) { return } } - got, err := server.HGETALL(tt.key) + got, err := server.HGetAll(tt.key) if (err != nil) != tt.wantErr { t.Errorf("HGETALL() error = %v, wantErr %v", err, tt.wantErr) return @@ -317,14 +317,14 @@ func TestEchoVault_HINCRBY(t *testing.T) { var got float64 var err error if tt.incr_type == HINCRBY { - got, err = server.HINCRBY(tt.key, tt.field, tt.increment_int) + got, err = server.HIncrBy(tt.key, tt.field, tt.increment_int) if (err != nil) != tt.wantErr { t.Errorf("HINCRBY() error = %v, wantErr %v", err, tt.wantErr) return } } if tt.incr_type == HINCRBYFLOAT { - got, err = server.HINCRBYFLOAT(tt.key, tt.field, tt.increment_float) + got, err = server.HIncrByFloat(tt.key, tt.field, tt.increment_float) if (err != nil) != tt.wantErr { t.Errorf("HINCRBYFLOAT() error = %v, wantErr %v", err, tt.wantErr) return @@ -378,7 +378,7 @@ func TestEchoVault_HKEYS(t *testing.T) { return } } - got, err := server.HKEYS(tt.key) + got, err := server.HKeys(tt.key) if (err != nil) != tt.wantErr { t.Errorf("HKEYS() error = %v, wantErr %v", err, tt.wantErr) return @@ -436,7 +436,7 @@ func TestEchoVault_HLEN(t *testing.T) { return } } - got, err := server.HLEN(tt.key) + got, err := server.HLen(tt.key) if (err != nil) != tt.wantErr { t.Errorf("HLEN() error = %v, wantErr %v", err, tt.wantErr) return @@ -455,7 +455,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { name string presetValue interface{} key string - options echovault.HRANDFIELDOptions + options echovault.HRandFieldOptions wantCount int want []string wantErr bool @@ -464,7 +464,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { name: "Get a random field", presetValue: map[string]interface{}{"field1": "value1", "field2": 123456789, "field3": 3.142}, key: "key1", - options: echovault.HRANDFIELDOptions{Count: 1}, + options: echovault.HRandFieldOptions{Count: 1}, wantCount: 1, want: []string{"field1", "field2", "field3"}, wantErr: false, @@ -473,7 +473,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { name: "Get a random field with a value", presetValue: map[string]interface{}{"field1": "value1", "field2": 123456789, "field3": 3.142}, key: "key2", - options: echovault.HRANDFIELDOptions{WithValues: true, Count: 1}, + options: echovault.HRandFieldOptions{WithValues: true, Count: 1}, wantCount: 2, want: []string{"field1", "value1", "field2", "123456789", "field3", "3.142"}, wantErr: false, @@ -488,7 +488,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { "field5": "value5", }, key: "key3", - options: echovault.HRANDFIELDOptions{Count: 3}, + options: echovault.HRandFieldOptions{Count: 3}, wantCount: 3, want: []string{"field1", "field2", "field3", "field4", "field5"}, wantErr: false, @@ -503,7 +503,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { "field5": "value5", }, key: "key4", - options: echovault.HRANDFIELDOptions{WithValues: true, Count: 3}, + options: echovault.HRandFieldOptions{WithValues: true, Count: 3}, wantCount: 6, want: []string{ "field1", "value1", "field2", "123456789", "field3", @@ -521,7 +521,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { "field5": "value5", }, key: "key5", - options: echovault.HRANDFIELDOptions{Count: 5}, + options: echovault.HRandFieldOptions{Count: 5}, wantCount: 5, want: []string{"field1", "field2", "field3", "field4", "field5"}, wantErr: false, @@ -536,7 +536,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { "field5": "value5", }, key: "key5", - options: echovault.HRANDFIELDOptions{WithValues: true, Count: 5}, + options: echovault.HRandFieldOptions{WithValues: true, Count: 5}, wantCount: 10, want: []string{ "field1", "value1", "field2", "123456789", "field3", @@ -548,7 +548,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { name: "Trying to get random field on a non hash map returns error", presetValue: "Default value", key: "key12", - options: echovault.HRANDFIELDOptions{}, + options: echovault.HRandFieldOptions{}, wantCount: 0, want: nil, wantErr: true, @@ -563,7 +563,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) { return } } - got, err := server.HRANDFIELD(tt.key, tt.options) + got, err := server.HRandField(tt.key, tt.options) if (err != nil) != tt.wantErr { t.Errorf("HRANDFIELD() error = %v, wantErr %v", err, tt.wantErr) return @@ -596,7 +596,7 @@ func TestEchoVault_HSET(t *testing.T) { name: "HSETNX set field on non-existent hash map", key: "key1", presetValue: nil, - hsetFunc: server.HSETNX, + hsetFunc: server.HSetNX, fieldValuePairs: map[string]string{"field1": "value1"}, want: 1, wantErr: false, @@ -605,7 +605,7 @@ func TestEchoVault_HSET(t *testing.T) { name: "HSETNX set field on existing hash map", key: "key2", presetValue: map[string]interface{}{"field1": "value1"}, - hsetFunc: server.HSETNX, + hsetFunc: server.HSetNX, fieldValuePairs: map[string]string{"field2": "value2"}, want: 1, wantErr: false, @@ -614,7 +614,7 @@ func TestEchoVault_HSET(t *testing.T) { name: "HSETNX skips operation when setting on existing field", key: "key3", presetValue: map[string]interface{}{"field1": "value1"}, - hsetFunc: server.HSETNX, + hsetFunc: server.HSetNX, fieldValuePairs: map[string]string{"field1": "value1"}, want: 0, wantErr: false, @@ -624,7 +624,7 @@ func TestEchoVault_HSET(t *testing.T) { key: "key4", presetValue: nil, fieldValuePairs: map[string]string{"field1": "value1", "field2": "value2"}, - hsetFunc: server.HSET, + hsetFunc: server.HSet, want: 2, wantErr: false, }, @@ -633,7 +633,7 @@ func TestEchoVault_HSET(t *testing.T) { key: "key5", presetValue: map[string]interface{}{"field1": "value1", "field2": "value2"}, fieldValuePairs: map[string]string{"field1": "value1-new", "field2": "value2-ne2", "field3": "value3"}, - hsetFunc: server.HSET, + hsetFunc: server.HSet, want: 3, wantErr: false, }, @@ -642,7 +642,7 @@ func TestEchoVault_HSET(t *testing.T) { key: "key6", presetValue: "Default preset value", fieldValuePairs: map[string]string{"field1": "value1"}, - hsetFunc: server.HSET, + hsetFunc: server.HSet, want: 0, wantErr: true, }, @@ -723,7 +723,7 @@ func TestEchoVault_HSTRLEN(t *testing.T) { return } } - got, err := server.HSTRLEN(tt.key, tt.fields...) + got, err := server.HStrLen(tt.key, tt.fields...) if (err != nil) != tt.wantErr { t.Errorf("HSTRLEN() error = %v, wantErr %v", err, tt.wantErr) return @@ -776,7 +776,7 @@ func TestEchoVault_HVALS(t *testing.T) { return } } - got, err := server.HVALS(tt.key) + got, err := server.HVals(tt.key) if (err != nil) != tt.wantErr { t.Errorf("HVALS() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/test/modules/hash/commands_test.go b/test/modules/hash/commands_test.go index 27a05897..f2fe29a1 100644 --- a/test/modules/hash/commands_test.go +++ b/test/modules/hash/commands_test.go @@ -19,10 +19,10 @@ import ( "context" "errors" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" + "github.com/echovault/echovault/internal/constants" "github.com/tidwall/resp" "net" "reflect" @@ -87,7 +87,7 @@ func getHandlerFuncParams(ctx context.Context, cmd []string, conn *net.Conn) int } func Test_HandleHSET(t *testing.T) { - // Tests for both HSET and HSETNX + // Tests for both HSet and HSetNX tests := []struct { name string preset bool @@ -232,7 +232,7 @@ func Test_HandleHSET(t *testing.T) { } func Test_HandleHINCRBY(t *testing.T) { - // Tests for both HINCRBY and HINCRBYFLOAT + // Tests for both HIncrBy and HIncrByFloat tests := []struct { name string preset bool diff --git a/test/modules/list/api_test.go b/test/modules/list/api_test.go index 44e85526..59231a2c 100644 --- a/test/modules/list/api_test.go +++ b/test/modules/list/api_test.go @@ -16,8 +16,8 @@ package list import ( "context" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/echovault" "reflect" "testing" ) @@ -87,7 +87,7 @@ func TestEchoVault_LLEN(t *testing.T) { return } } - got, err := server.LLEN(tt.key) + got, err := server.LLen(tt.key) if (err != nil) != tt.wantErr { t.Errorf("LLEN() error = %v, wantErr %v", err, tt.wantErr) return @@ -175,7 +175,7 @@ func TestEchoVault_LINDEX(t *testing.T) { } } t.Run(tt.name, func(t *testing.T) { - got, err := server.LINDEX(tt.key, tt.index) + got, err := server.LIndex(tt.key, tt.index) if (err != nil) != tt.wantErr { t.Errorf("LINDEX() error = %v, wantErr %v", err, tt.wantErr) return @@ -345,7 +345,7 @@ func TestEchoVault_LMOVE(t *testing.T) { } } } - got, err := server.LMOVE(tt.source, tt.destination, tt.whereFrom, tt.whereTo) + got, err := server.LMove(tt.source, tt.destination, tt.whereFrom, tt.whereTo) if (err != nil) != tt.wantErr { t.Errorf("LMOVE() error = %v, wantErr %v", err, tt.wantErr) return @@ -374,7 +374,7 @@ func TestEchoVault_POP(t *testing.T) { preset: true, presetValue: []interface{}{"value1", "value2", "value3", "value4"}, key: "key1", - popFunc: server.LPOP, + popFunc: server.LPop, want: "value1", wantErr: false, }, @@ -383,7 +383,7 @@ func TestEchoVault_POP(t *testing.T) { preset: true, presetValue: []interface{}{"value1", "value2", "value3", "value4"}, key: "key2", - popFunc: server.RPOP, + popFunc: server.RPop, want: "value4", wantErr: false, }, @@ -392,7 +392,7 @@ func TestEchoVault_POP(t *testing.T) { preset: true, key: "key3", presetValue: "Default value", - popFunc: server.LPOP, + popFunc: server.LPop, want: "", wantErr: true, }, @@ -401,7 +401,7 @@ func TestEchoVault_POP(t *testing.T) { preset: true, presetValue: "Default value", key: "key6", - popFunc: server.RPOP, + popFunc: server.RPop, want: "", wantErr: true, }, @@ -436,8 +436,8 @@ func TestEchoVault_LPUSH(t *testing.T) { key string values []string presetValue interface{} - lpushFunc func(key string, values ...string) (string, error) - want string + lpushFunc func(key string, values ...string) (int, error) + want int wantErr bool }{ { @@ -446,8 +446,8 @@ func TestEchoVault_LPUSH(t *testing.T) { presetValue: []interface{}{"1", "2", "4", "5"}, key: "key1", values: []string{"value1", "value2"}, - lpushFunc: server.LPUSHX, - want: "OK", + lpushFunc: server.LPushX, + want: 6, wantErr: false, }, { @@ -456,8 +456,8 @@ func TestEchoVault_LPUSH(t *testing.T) { presetValue: []interface{}{"1", "2", "4", "5"}, key: "key2", values: []string{"value1", "value2"}, - lpushFunc: server.LPUSH, - want: "OK", + lpushFunc: server.LPush, + want: 6, wantErr: false, }, { @@ -466,8 +466,8 @@ func TestEchoVault_LPUSH(t *testing.T) { presetValue: nil, key: "key3", values: []string{"value1", "value2"}, - lpushFunc: server.LPUSH, - want: "OK", + lpushFunc: server.LPush, + want: 2, wantErr: false, }, { @@ -476,8 +476,8 @@ func TestEchoVault_LPUSH(t *testing.T) { presetValue: nil, key: "key4", values: []string{"value1", "value2"}, - lpushFunc: server.LPUSHX, - want: "", + lpushFunc: server.LPushX, + want: 0, wantErr: true, }, } @@ -511,8 +511,8 @@ func TestEchoVault_RPUSH(t *testing.T) { key string values []string presetValue interface{} - rpushFunc func(key string, values ...string) (string, error) - want string + rpushFunc func(key string, values ...string) (int, error) + want int wantErr bool }{ { @@ -521,8 +521,8 @@ func TestEchoVault_RPUSH(t *testing.T) { presetValue: nil, key: "key1", values: []string{"value1", "value2"}, - rpushFunc: server.RPUSH, - want: "OK", + rpushFunc: server.RPush, + want: 2, wantErr: false, }, { @@ -531,8 +531,8 @@ func TestEchoVault_RPUSH(t *testing.T) { presetValue: nil, key: "key2", values: []string{"value1", "value2"}, - rpushFunc: server.RPUSHX, - want: "", + rpushFunc: server.RPushX, + want: 0, wantErr: true, }, } @@ -664,7 +664,7 @@ func TestEchoVault_LRANGE(t *testing.T) { return } } - got, err := server.LRANGE(tt.key, tt.start, tt.end) + got, err := server.LRange(tt.key, tt.start, tt.end) if (err != nil) != tt.wantErr { t.Errorf("LRANGE() error = %v, wantErr %v", err, tt.wantErr) return @@ -729,7 +729,7 @@ func TestEchoVault_LREM(t *testing.T) { } } t.Run(tt.name, func(t *testing.T) { - got, err := server.LREM(tt.key, tt.count, tt.value) + got, err := server.LRem(tt.key, tt.count, tt.value) if (err != nil) != tt.wantErr { t.Errorf("LREM() error = %v, wantErr %v", err, tt.wantErr) return @@ -834,7 +834,7 @@ func TestEchoVault_LSET(t *testing.T) { return } } - got, err := server.LSET(tt.key, tt.index, tt.value) + got, err := server.LSet(tt.key, tt.index, tt.value) if (err != nil) != tt.wantErr { t.Errorf("LSET() error = %v, wantErr %v", err, tt.wantErr) return @@ -942,7 +942,7 @@ func TestEchoVault_LTRIM(t *testing.T) { return } } - got, err := server.LTRIM(tt.key, tt.start, tt.end) + got, err := server.LTrim(tt.key, tt.start, tt.end) if (err != nil) != tt.wantErr { t.Errorf("LTRIM() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/test/modules/list/commands_test.go b/test/modules/list/commands_test.go index a2272d28..f748cf4b 100644 --- a/test/modules/list/commands_test.go +++ b/test/modules/list/commands_test.go @@ -19,10 +19,10 @@ import ( "context" "errors" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" + "github.com/echovault/echovault/internal/constants" "github.com/tidwall/resp" "net" "reflect" @@ -1241,7 +1241,7 @@ func Test_HandleLPUSH(t *testing.T) { key string presetValue interface{} command []string - expectedResponse interface{} + expectedResponse int expectedValue []interface{} expectedError error }{ @@ -1251,7 +1251,7 @@ func Test_HandleLPUSH(t *testing.T) { key: "LpushKey1", presetValue: []interface{}{"1", "2", "4", "5"}, command: []string{"LPUSHX", "LpushKey1", "value1", "value2"}, - expectedResponse: "OK", + expectedResponse: 6, expectedValue: []interface{}{"value1", "value2", "1", "2", "4", "5"}, expectedError: nil, }, @@ -1261,7 +1261,7 @@ func Test_HandleLPUSH(t *testing.T) { key: "LpushKey2", presetValue: []interface{}{"1", "2", "4", "5"}, command: []string{"LPUSH", "LpushKey2", "value1", "value2"}, - expectedResponse: "OK", + expectedResponse: 6, expectedValue: []interface{}{"value1", "value2", "1", "2", "4", "5"}, expectedError: nil, }, @@ -1271,7 +1271,7 @@ func Test_HandleLPUSH(t *testing.T) { key: "LpushKey3", presetValue: nil, command: []string{"LPUSH", "LpushKey3", "value1", "value2"}, - expectedResponse: "OK", + expectedResponse: 2, expectedValue: []interface{}{"value1", "value2"}, expectedError: nil, }, @@ -1281,7 +1281,7 @@ func Test_HandleLPUSH(t *testing.T) { key: "LpushKey5", presetValue: nil, command: []string{"LPUSH", "LpushKey5"}, - expectedResponse: nil, + expectedResponse: 0, expectedValue: nil, expectedError: errors.New(constants.WrongArgsResponse), }, @@ -1291,7 +1291,7 @@ func Test_HandleLPUSH(t *testing.T) { key: "LpushKey6", presetValue: nil, command: []string{"LPUSHX", "LpushKey7", "count", "value1"}, - expectedResponse: nil, + expectedResponse: 0, expectedValue: nil, expectedError: errors.New("LPUSHX command on non-list item"), }, @@ -1329,8 +1329,8 @@ func Test_HandleLPUSH(t *testing.T) { if err != nil { t.Error(err) } - if rv.String() != test.expectedResponse { - t.Errorf("expected \"%s\" response, got \"%s\"", test.expectedResponse, rv.String()) + if rv.Integer() != test.expectedResponse { + t.Errorf("expected \"%d\" response, got \"%s\"", test.expectedResponse, rv.String()) } if _, err = mockServer.KeyRLock(ctx, test.key); err != nil { t.Error(err) @@ -1359,7 +1359,7 @@ func Test_HandleRPUSH(t *testing.T) { key string presetValue interface{} command []string - expectedResponse interface{} + expectedResponse int expectedValue []interface{} expectedError error }{ @@ -1369,7 +1369,7 @@ func Test_HandleRPUSH(t *testing.T) { key: "RpushKey1", presetValue: []interface{}{"1", "2", "4", "5"}, command: []string{"RPUSHX", "RpushKey1", "value1", "value2"}, - expectedResponse: "OK", + expectedResponse: 6, expectedValue: []interface{}{"1", "2", "4", "5", "value1", "value2"}, expectedError: nil, }, @@ -1379,7 +1379,7 @@ func Test_HandleRPUSH(t *testing.T) { key: "RpushKey2", presetValue: []interface{}{"1", "2", "4", "5"}, command: []string{"RPUSH", "RpushKey2", "value1", "value2"}, - expectedResponse: "OK", + expectedResponse: 6, expectedValue: []interface{}{"1", "2", "4", "5", "value1", "value2"}, expectedError: nil, }, @@ -1389,7 +1389,7 @@ func Test_HandleRPUSH(t *testing.T) { key: "RpushKey3", presetValue: nil, command: []string{"RPUSH", "RpushKey3", "value1", "value2"}, - expectedResponse: "OK", + expectedResponse: 2, expectedValue: []interface{}{"value1", "value2"}, expectedError: nil, }, @@ -1399,7 +1399,7 @@ func Test_HandleRPUSH(t *testing.T) { key: "RpushKey5", presetValue: nil, command: []string{"RPUSH", "RpushKey5"}, - expectedResponse: nil, + expectedResponse: 0, expectedValue: nil, expectedError: errors.New(constants.WrongArgsResponse), }, @@ -1409,7 +1409,7 @@ func Test_HandleRPUSH(t *testing.T) { key: "RpushKey6", presetValue: nil, command: []string{"RPUSHX", "RpushKey7", "count", "value1"}, - expectedResponse: nil, + expectedResponse: 0, expectedValue: nil, expectedError: errors.New("RPUSHX command on non-list item"), }, @@ -1447,8 +1447,8 @@ func Test_HandleRPUSH(t *testing.T) { if err != nil { t.Error(err) } - if rv.String() != test.expectedResponse { - t.Errorf("expected \"%s\" response, got \"%s\"", test.expectedResponse, rv.String()) + if rv.Integer() != test.expectedResponse { + t.Errorf("expected \"%d\" response, got \"%s\"", test.expectedResponse, rv.String()) } if _, err = mockServer.KeyRLock(ctx, test.key); err != nil { t.Error(err) diff --git a/test/modules/pubsub/commands_test.go b/test/modules/pubsub/commands_test.go index 4774c8c0..72febf19 100644 --- a/test/modules/pubsub/commands_test.go +++ b/test/modules/pubsub/commands_test.go @@ -18,11 +18,11 @@ import ( "bytes" "context" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" + "github.com/echovault/echovault/internal/constants" "github.com/echovault/echovault/internal/modules/pubsub" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" "github.com/tidwall/resp" "net" "reflect" diff --git a/test/modules/set/api_test.go b/test/modules/set/api_test.go index 6c085b8a..fb90f04f 100644 --- a/test/modules/set/api_test.go +++ b/test/modules/set/api_test.go @@ -16,9 +16,9 @@ package set import ( "context" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/modules/set" - "github.com/echovault/echovault/pkg/echovault" "reflect" "slices" "testing" @@ -89,7 +89,7 @@ func TestEchoVault_SADD(t *testing.T) { return } } - got, err := server.SADD(tt.key, tt.members...) + got, err := server.SAdd(tt.key, tt.members...) if (err != nil) != tt.wantErr { t.Errorf("SADD() error = %v, wantErr %v", err, tt.wantErr) return @@ -142,7 +142,7 @@ func TestEchoVault_SCARD(t *testing.T) { return } } - got, err := server.SCARD(tt.key) + got, err := server.SCard(tt.key) if (err != nil) != tt.wantErr { t.Errorf("SCARD() error = %v, wantErr %v", err, tt.wantErr) return @@ -229,7 +229,7 @@ func TestEchoVault_SDIFF(t *testing.T) { } } } - got, err := server.SDIFF(tt.keys...) + got, err := server.SDiff(tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("SDIFF() error = %v, wantErr %v", err, tt.wantErr) return @@ -327,7 +327,7 @@ func TestEchoVault_SDIFFSTORE(t *testing.T) { } } } - got, err := server.SDIFFSTORE(tt.destination, tt.keys...) + got, err := server.SDiffStore(tt.destination, tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("SDIFFSTORE() error = %v, wantErr %v", err, tt.wantErr) return @@ -414,7 +414,7 @@ func TestEchoVault_SINTER(t *testing.T) { } } } - got, err := server.SINTER(tt.keys...) + got, err := server.SInter(tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("SINTER() error = %v, wantErr %v", err, tt.wantErr) return @@ -523,7 +523,7 @@ func TestEchoVault_SINTERCARD(t *testing.T) { } } } - got, err := server.SINTERCARD(tt.keys, tt.limit) + got, err := server.SInterCard(tt.keys, tt.limit) if (err != nil) != tt.wantErr { t.Errorf("SINTERCARD() error = %v, wantErr %v", err, tt.wantErr) return @@ -616,7 +616,7 @@ func TestEchoVault_SINTERSTORE(t *testing.T) { } } } - got, err := server.SINTERSTORE(tt.destination, tt.keys...) + got, err := server.SInterStore(tt.destination, tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("SINTERSTORE() error = %v, wantErr %v", err, tt.wantErr) return @@ -673,7 +673,7 @@ func TestEchoVault_SISMEMBER(t *testing.T) { return } } - got, err := server.SISMEMBER(tt.key, tt.member) + got, err := server.SisMember(tt.key, tt.member) if (err != nil) != tt.wantErr { t.Errorf("SISMEMBER() error = %v, wantErr %v", err, tt.wantErr) return @@ -726,7 +726,7 @@ func TestEchoVault_SMEMBERS(t *testing.T) { return } } - got, err := server.SMEMBERS(tt.key) + got, err := server.SMembers(tt.key) if (err != nil) != tt.wantErr { t.Errorf("SMEMBERS() error = %v, wantErr %v", err, tt.wantErr) return @@ -807,7 +807,7 @@ func TestEchoVault_SMISMEMBER(t *testing.T) { return } } - got, err := server.SMISMEMBER(tt.key, tt.members...) + got, err := server.SMisMember(tt.key, tt.members...) if (err != nil) != tt.wantErr { t.Errorf("SMISMEMBER() error = %v, wantErr %v", err, tt.wantErr) return @@ -891,7 +891,7 @@ func TestEchoVault_SMOVE(t *testing.T) { } } } - got, err := server.SMOVE(tt.source, tt.destination, tt.member) + got, err := server.SMove(tt.source, tt.destination, tt.member) if (err != nil) != tt.wantErr { t.Errorf("SMOVE() error = %v, wantErr %v", err, tt.wantErr) return @@ -940,7 +940,7 @@ func TestEchoVault_SPOP(t *testing.T) { return } } - got, err := server.SPOP(tt.key, tt.count) + got, err := server.SPop(tt.key, tt.count) if (err != nil) != tt.wantErr { t.Errorf("SPOP() error = %v, wantErr %v", err, tt.wantErr) return @@ -1003,7 +1003,7 @@ func TestEchoVault_SRANDMEMBER(t *testing.T) { return } } - got, err := server.SRANDMEMBER(tt.key, tt.count) + got, err := server.SRandMember(tt.key, tt.count) if (err != nil) != tt.wantErr { t.Errorf("SRANDMEMBER() error = %v, wantErr %v", err, tt.wantErr) return @@ -1066,7 +1066,7 @@ func TestEchoVault_SREM(t *testing.T) { return } } - got, err := server.SREM(tt.key, tt.members...) + got, err := server.SRem(tt.key, tt.members...) if (err != nil) != tt.wantErr { t.Errorf("SREM() error = %v, wantErr %v", err, tt.wantErr) return @@ -1146,7 +1146,7 @@ func TestEchoVault_SUNION(t *testing.T) { } } } - got, err := server.SUNION(tt.keys...) + got, err := server.SUnion(tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("SUNION() error = %v, wantErr %v", err, tt.wantErr) return @@ -1221,7 +1221,7 @@ func TestEchoVault_SUNIONSTORE(t *testing.T) { } } } - got, err := server.SUNIONSTORE(tt.destination, tt.keys...) + got, err := server.SUnionStore(tt.destination, tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("SUNIONSTORE() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/test/modules/set/commands_test.go b/test/modules/set/commands_test.go index 5a107ab5..b6305f89 100644 --- a/test/modules/set/commands_test.go +++ b/test/modules/set/commands_test.go @@ -19,11 +19,11 @@ import ( "context" "errors" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" + "github.com/echovault/echovault/internal/constants" "github.com/echovault/echovault/internal/modules/set" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" "github.com/tidwall/resp" "net" "reflect" diff --git a/test/modules/sorted_set/api_test.go b/test/modules/sorted_set/api_test.go index 8dcd57f5..71f0b57a 100644 --- a/test/modules/sorted_set/api_test.go +++ b/test/modules/sorted_set/api_test.go @@ -16,10 +16,10 @@ package sorted_set import ( "context" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" ss "github.com/echovault/echovault/internal/modules/sorted_set" - "github.com/echovault/echovault/pkg/echovault" "math" "reflect" "strconv" @@ -55,7 +55,7 @@ func TestEchoVault_ZADD(t *testing.T) { presetValue *ss.SortedSet key string entries map[string]float64 - options echovault.ZADDOptions + options echovault.ZAddOptions want int wantErr bool }{ @@ -71,7 +71,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member4": math.Inf(-1), "member5": math.Inf(1), }, - options: echovault.ZADDOptions{}, + options: echovault.ZAddOptions{}, want: 5, wantErr: false, }, @@ -89,7 +89,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member4": 67.77, "member5": 10, }, - options: echovault.ZADDOptions{NX: true}, + options: echovault.ZAddOptions{NX: true}, want: 2, wantErr: false, }, @@ -107,7 +107,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member2": 67.77, "member3": 10, }, - options: echovault.ZADDOptions{NX: true}, + options: echovault.ZAddOptions{NX: true}, want: 0, wantErr: false, }, @@ -126,7 +126,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member3": 15, "member4": 99.75, }, - options: echovault.ZADDOptions{XX: true, CH: true}, + options: echovault.ZAddOptions{XX: true, CH: true}, want: 3, wantErr: false, }, @@ -144,7 +144,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member5": 100.5, "member6": 15, }, - options: echovault.ZADDOptions{XX: true}, + options: echovault.ZAddOptions{XX: true}, want: 0, wantErr: false, }, @@ -164,7 +164,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member4": 100.5, "member5": 15, }, - options: echovault.ZADDOptions{XX: true, CH: true, GT: true}, + options: echovault.ZAddOptions{XX: true, CH: true, GT: true}, want: 1, wantErr: false, }, @@ -184,7 +184,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member4": 100.5, "member5": 15, }, - options: echovault.ZADDOptions{XX: true, LT: true}, + options: echovault.ZAddOptions{XX: true, LT: true}, want: 0, wantErr: false, }, @@ -202,7 +202,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member4": 100.5, "member5": 15, }, - options: echovault.ZADDOptions{XX: true, LT: true, CH: true}, + options: echovault.ZAddOptions{XX: true, LT: true, CH: true}, want: 1, wantErr: false, }, @@ -218,7 +218,7 @@ func TestEchoVault_ZADD(t *testing.T) { entries: map[string]float64{ "member3": 5.5, }, - options: echovault.ZADDOptions{INCR: true}, + options: echovault.ZAddOptions{INCR: true}, want: 0, wantErr: false, }, @@ -231,7 +231,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member1": 3.5, "member5": 15, }, - options: echovault.ZADDOptions{NX: true, LT: true, CH: true}, + options: echovault.ZAddOptions{NX: true, LT: true, CH: true}, want: 0, wantErr: true, }, @@ -244,7 +244,7 @@ func TestEchoVault_ZADD(t *testing.T) { "member1": 10.5, "member2": 12.5, }, - options: echovault.ZADDOptions{INCR: true}, + options: echovault.ZAddOptions{INCR: true}, want: 0, wantErr: true, }, @@ -258,7 +258,7 @@ func TestEchoVault_ZADD(t *testing.T) { return } } - got, err := server.ZADD(tt.key, tt.entries, tt.options) + got, err := server.ZAdd(tt.key, tt.entries, tt.options) if (err != nil) != tt.wantErr { t.Errorf("ZADD() error = %v, wantErr %v", err, tt.wantErr) return @@ -319,7 +319,7 @@ func TestEchoVault_ZCARD(t *testing.T) { return } } - got, err := server.ZCARD(tt.key) + got, err := server.ZCard(tt.key) if (err != nil) != tt.wantErr { t.Errorf("ZCARD() error = %v, wantErr %v", err, tt.wantErr) return @@ -418,7 +418,7 @@ func TestEchoVault_ZCOUNT(t *testing.T) { return } } - got, err := server.ZCOUNT(tt.key, tt.min, tt.max) + got, err := server.ZCount(tt.key, tt.min, tt.max) if (err != nil) != tt.wantErr { t.Errorf("ZCOUNT() error = %v, wantErr %v", err, tt.wantErr) return @@ -568,7 +568,7 @@ func TestEchoVault_ZDIFF(t *testing.T) { } } } - got, err := server.ZDIFF(tt.withscores, tt.keys...) + got, err := server.ZDiff(tt.withscores, tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("ZDIFF() error = %v, wantErr %v", err, tt.wantErr) return @@ -687,7 +687,7 @@ func TestEchoVault_ZDIFFSTORE(t *testing.T) { } } } - got, err := server.ZDIFFSTORE(tt.destination, tt.keys...) + got, err := server.ZDiffStore(tt.destination, tt.keys...) if (err != nil) != tt.wantErr { t.Errorf("ZDIFFSTORE() error = %v, wantErr %v", err, tt.wantErr) return @@ -835,7 +835,7 @@ func TestEchoVault_ZINCRBY(t *testing.T) { return } } - got, err := server.ZINCRBY(tt.key, tt.increment, tt.member) + got, err := server.ZIncrBy(tt.key, tt.increment, tt.member) if (err != nil) != tt.wantErr { t.Errorf("ZINCRBY() error = %v, wantErr %v", err, tt.wantErr) return @@ -855,7 +855,7 @@ func TestEchoVault_ZINTER(t *testing.T) { preset bool presetValues map[string]interface{} keys []string - options echovault.ZINTEROptions + options echovault.ZInterOptions want map[string]float64 wantErr bool }{ @@ -875,7 +875,7 @@ func TestEchoVault_ZINTER(t *testing.T) { }), }, keys: []string{"key1", "key2"}, - options: echovault.ZINTEROptions{}, + options: echovault.ZInterOptions{}, want: map[string]float64{"three": 0, "four": 0, "five": 0}, wantErr: false, }, @@ -903,7 +903,7 @@ func TestEchoVault_ZINTER(t *testing.T) { }), }, keys: []string{"key3", "key4", "key5"}, - options: echovault.ZINTEROptions{WithScores: true}, + options: echovault.ZInterOptions{WithScores: true}, want: map[string]float64{"one": 3, "eight": 24}, wantErr: false, }, @@ -931,7 +931,7 @@ func TestEchoVault_ZINTER(t *testing.T) { }), }, keys: []string{"key6", "key7", "key8"}, - options: echovault.ZINTEROptions{Aggregate: "MIN", WithScores: true}, + options: echovault.ZInterOptions{Aggregate: "MIN", WithScores: true}, want: map[string]float64{"one": 1, "eight": 8}, wantErr: false, }, @@ -958,7 +958,7 @@ func TestEchoVault_ZINTER(t *testing.T) { }), }, keys: []string{"key9", "key10", "key11"}, - options: echovault.ZINTEROptions{WithScores: true, Aggregate: "MAX"}, + options: echovault.ZInterOptions{WithScores: true, Aggregate: "MAX"}, want: map[string]float64{"one": 1000, "eight": 800}, wantErr: false, }, @@ -986,7 +986,7 @@ func TestEchoVault_ZINTER(t *testing.T) { }), }, keys: []string{"key12", "key13", "key14"}, - options: echovault.ZINTEROptions{WithScores: true, Aggregate: "SUM", Weights: []float64{1, 5, 3}}, + options: echovault.ZInterOptions{WithScores: true, Aggregate: "SUM", Weights: []float64{1, 5, 3}}, want: map[string]float64{"one": 3105, "eight": 2808}, wantErr: false, }, @@ -1014,7 +1014,7 @@ func TestEchoVault_ZINTER(t *testing.T) { }), }, keys: []string{"key15", "key16", "key17"}, - options: echovault.ZINTEROptions{WithScores: true, Aggregate: "MAX", Weights: []float64{1, 5, 3}}, + options: echovault.ZInterOptions{WithScores: true, Aggregate: "MAX", Weights: []float64{1, 5, 3}}, want: map[string]float64{"one": 3000, "eight": 2400}, wantErr: false, }, @@ -1042,7 +1042,7 @@ func TestEchoVault_ZINTER(t *testing.T) { }), }, keys: []string{"key18", "key19", "key20"}, - options: echovault.ZINTEROptions{WithScores: true, Aggregate: "MIN", Weights: []float64{1, 5, 3}}, + options: echovault.ZInterOptions{WithScores: true, Aggregate: "MIN", Weights: []float64{1, 5, 3}}, want: map[string]float64{"one": 5, "eight": 8}, wantErr: false, }, @@ -1059,7 +1059,7 @@ func TestEchoVault_ZINTER(t *testing.T) { "key22": ss.NewSortedSet([]ss.MemberParam{{Value: "one", Score: 1}}), }, keys: []string{"key21", "key22"}, - options: echovault.ZINTEROptions{Weights: []float64{1, 2, 3}}, + options: echovault.ZInterOptions{Weights: []float64{1, 2, 3}}, want: nil, wantErr: true, }, @@ -1079,7 +1079,7 @@ func TestEchoVault_ZINTER(t *testing.T) { "key25": ss.NewSortedSet([]ss.MemberParam{{Value: "one", Score: 1}}), }, keys: []string{"key23", "key24", "key25"}, - options: echovault.ZINTEROptions{Weights: []float64{5, 4}}, + options: echovault.ZInterOptions{Weights: []float64{5, 4}}, want: nil, wantErr: true, }, @@ -1092,7 +1092,7 @@ func TestEchoVault_ZINTER(t *testing.T) { "key28": ss.NewSortedSet([]ss.MemberParam{{Value: "one", Score: 1}}), }, keys: []string{}, - options: echovault.ZINTEROptions{}, + options: echovault.ZInterOptions{}, want: nil, wantErr: true, }, @@ -1110,7 +1110,7 @@ func TestEchoVault_ZINTER(t *testing.T) { "key31": ss.NewSortedSet([]ss.MemberParam{{Value: "one", Score: 1}}), }, keys: []string{"key29", "key30", "key31"}, - options: echovault.ZINTEROptions{}, + options: echovault.ZInterOptions{}, want: nil, wantErr: true, }, @@ -1130,7 +1130,7 @@ func TestEchoVault_ZINTER(t *testing.T) { }), }, keys: []string{"non-existent", "key32", "key33"}, - options: echovault.ZINTEROptions{}, + options: echovault.ZInterOptions{}, want: map[string]float64{}, wantErr: false, }, @@ -1146,7 +1146,7 @@ func TestEchoVault_ZINTER(t *testing.T) { } } } - got, err := server.ZINTER(tt.keys, tt.options) + got, err := server.ZInter(tt.keys, tt.options) if (err != nil) != tt.wantErr { t.Errorf("ZINTER() error = %v, wantErr %v", err, tt.wantErr) return @@ -1167,7 +1167,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { presetValues map[string]interface{} destination string keys []string - options echovault.ZINTERSTOREOptions + options echovault.ZInterStoreOptions want int wantErr bool }{ @@ -1188,7 +1188,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination1", keys: []string{"key1", "key2"}, - options: echovault.ZINTERSTOREOptions{}, + options: echovault.ZInterStoreOptions{}, want: 3, wantErr: false, }, @@ -1217,7 +1217,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination2", keys: []string{"key3", "key4", "key5"}, - options: echovault.ZINTERSTOREOptions{WithScores: true}, + options: echovault.ZInterStoreOptions{WithScores: true}, want: 2, wantErr: false, }, @@ -1246,7 +1246,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination3", keys: []string{"key6", "key7", "key8"}, - options: echovault.ZINTERSTOREOptions{WithScores: true, Aggregate: "MIN"}, + options: echovault.ZInterStoreOptions{WithScores: true, Aggregate: "MIN"}, want: 2, wantErr: false, }, @@ -1275,7 +1275,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination4", keys: []string{"key9", "key10", "key11"}, - options: echovault.ZINTERSTOREOptions{WithScores: true, Aggregate: "MAX"}, + options: echovault.ZInterStoreOptions{WithScores: true, Aggregate: "MAX"}, want: 2, wantErr: false, }, @@ -1304,7 +1304,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination5", keys: []string{"key12", "key13", "key14"}, - options: echovault.ZINTERSTOREOptions{WithScores: true, Aggregate: "SUM", Weights: []float64{1, 5, 3}}, + options: echovault.ZInterStoreOptions{WithScores: true, Aggregate: "SUM", Weights: []float64{1, 5, 3}}, want: 2, wantErr: false, }, @@ -1333,7 +1333,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination6", keys: []string{"key15", "key16", "key17"}, - options: echovault.ZINTERSTOREOptions{WithScores: true, Aggregate: "MAX", Weights: []float64{1, 5, 3}}, + options: echovault.ZInterStoreOptions{WithScores: true, Aggregate: "MAX", Weights: []float64{1, 5, 3}}, want: 2, wantErr: false, }, @@ -1362,7 +1362,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination7", keys: []string{"key18", "key19", "key20"}, - options: echovault.ZINTERSTOREOptions{WithScores: true, Aggregate: "MIN", Weights: []float64{1, 5, 3}}, + options: echovault.ZInterStoreOptions{WithScores: true, Aggregate: "MIN", Weights: []float64{1, 5, 3}}, want: 2, wantErr: false, }, @@ -1380,7 +1380,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination8", keys: []string{"key21", "key22"}, - options: echovault.ZINTERSTOREOptions{Weights: []float64{1, 2, 3}}, + options: echovault.ZInterStoreOptions{Weights: []float64{1, 2, 3}}, want: 0, wantErr: true, }, @@ -1401,7 +1401,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination9", keys: []string{"key23", "key24"}, - options: echovault.ZINTERSTOREOptions{Weights: []float64{5}}, + options: echovault.ZInterStoreOptions{Weights: []float64{5}}, want: 0, wantErr: true, }, @@ -1415,7 +1415,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination10", keys: []string{}, - options: echovault.ZINTERSTOREOptions{Weights: []float64{5, 4}}, + options: echovault.ZInterStoreOptions{Weights: []float64{5, 4}}, want: 0, wantErr: true, }, @@ -1434,7 +1434,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination11", keys: []string{"key29", "key30", "key31"}, - options: echovault.ZINTERSTOREOptions{}, + options: echovault.ZInterStoreOptions{}, want: 0, wantErr: true, }, @@ -1455,7 +1455,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { }, destination: "destination12", keys: []string{"non-existent", "key32", "key33"}, - options: echovault.ZINTERSTOREOptions{}, + options: echovault.ZInterStoreOptions{}, want: 0, wantErr: false, }, @@ -1471,7 +1471,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) { } } } - got, err := server.ZINTERSTORE(tt.destination, tt.keys, tt.options) + got, err := server.ZInterStore(tt.destination, tt.keys, tt.options) if (err != nil) != tt.wantErr { t.Errorf("ZINTERSTORE() error = %v, wantErr %v", err, tt.wantErr) return @@ -1562,7 +1562,7 @@ func TestEchoVault_ZLEXCOUNT(t *testing.T) { return } } - got, err := server.ZLEXCOUNT(tt.key, tt.min, tt.max) + got, err := server.ZLexCount(tt.key, tt.min, tt.max) if (err != nil) != tt.wantErr { t.Errorf("ZLEXCOUNT() error = %v, wantErr %v", err, tt.wantErr) return @@ -1582,7 +1582,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { preset bool presetValues map[string]interface{} keys []string - options echovault.ZMPOPOptions + options echovault.ZMPopOptions want [][]string wantErr bool }{ @@ -1597,7 +1597,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { }), }, keys: []string{"key1"}, - options: echovault.ZMPOPOptions{}, + options: echovault.ZMPopOptions{}, want: [][]string{ {"one", "1"}, }, @@ -1614,7 +1614,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { }), }, keys: []string{"key2"}, - options: echovault.ZMPOPOptions{Min: true}, + options: echovault.ZMPopOptions{Min: true}, want: [][]string{ {"one", "1"}, }, @@ -1631,7 +1631,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { }), }, keys: []string{"key3"}, - options: echovault.ZMPOPOptions{Max: true}, + options: echovault.ZMPopOptions{Max: true}, want: [][]string{ {"five", "5"}, }, @@ -1648,7 +1648,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { }), }, keys: []string{"key4"}, - options: echovault.ZMPOPOptions{Min: true, Count: 5}, + options: echovault.ZMPopOptions{Min: true, Count: 5}, want: [][]string{ {"one", "1"}, {"two", "2"}, {"three", "3"}, {"four", "4"}, {"five", "5"}, @@ -1666,7 +1666,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { }), }, keys: []string{"key5"}, - options: echovault.ZMPOPOptions{Max: true, Count: 5}, + options: echovault.ZMPopOptions{Max: true, Count: 5}, want: [][]string{{"two", "2"}, {"three", "3"}, {"four", "4"}, {"five", "5"}, {"six", "6"}}, wantErr: false, }, @@ -1682,7 +1682,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { }), }, keys: []string{"key6", "key7"}, - options: echovault.ZMPOPOptions{Max: true, Count: 5}, + options: echovault.ZMPopOptions{Max: true, Count: 5}, want: [][]string{{"two", "2"}, {"three", "3"}, {"four", "4"}, {"five", "5"}, {"six", "6"}}, wantErr: false, }, @@ -1700,7 +1700,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { }), }, keys: []string{"key8", "key9", "key10", "key11"}, - options: echovault.ZMPOPOptions{Min: true, Count: 5}, + options: echovault.ZMPopOptions{Min: true, Count: 5}, want: [][]string{{"one", "1"}, {"two", "2"}, {"three", "3"}, {"four", "4"}, {"five", "5"}}, wantErr: false, }, @@ -1716,7 +1716,7 @@ func TestEchoVault_ZMPOP(t *testing.T) { } } } - got, err := server.ZMPOP(tt.keys, tt.options) + got, err := server.ZMPop(tt.keys, tt.options) if (err != nil) != tt.wantErr { t.Errorf("ZMPOP() error = %v, wantErr %v", err, tt.wantErr) return @@ -1782,7 +1782,7 @@ func TestEchoVault_ZMSCORE(t *testing.T) { return } } - got, err := server.ZMSCORE(tt.key, tt.members...) + got, err := server.ZMScore(tt.key, tt.members...) if (err != nil) != tt.wantErr { t.Errorf("ZMSCORE() error = %v, wantErr %v", err, tt.wantErr) return @@ -1830,7 +1830,7 @@ func TestEchoVault_ZPOP(t *testing.T) { }), key: "key1", count: 1, - popFunc: server.ZPOPMIN, + popFunc: server.ZPopMin, want: [][]string{ {"one", "1"}, }, @@ -1846,7 +1846,7 @@ func TestEchoVault_ZPOP(t *testing.T) { }), key: "key2", count: 1, - popFunc: server.ZPOPMAX, + popFunc: server.ZPopMax, want: [][]string{{"five", "5"}}, wantErr: false, }, @@ -1858,7 +1858,7 @@ func TestEchoVault_ZPOP(t *testing.T) { {Value: "three", Score: 3}, {Value: "four", Score: 4}, {Value: "five", Score: 5}, {Value: "six", Score: 6}, }), - popFunc: server.ZPOPMIN, + popFunc: server.ZPopMin, key: "key3", count: 5, want: [][]string{ @@ -1875,7 +1875,7 @@ func TestEchoVault_ZPOP(t *testing.T) { {Value: "three", Score: 3}, {Value: "four", Score: 4}, {Value: "five", Score: 5}, {Value: "six", Score: 6}, }), - popFunc: server.ZPOPMAX, + popFunc: server.ZPopMax, key: "key4", count: 5, want: [][]string{{"two", "2"}, {"three", "3"}, {"four", "4"}, {"five", "5"}, {"six", "6"}}, @@ -1885,7 +1885,7 @@ func TestEchoVault_ZPOP(t *testing.T) { name: "Throw an error when trying to pop from an element that's not a sorted set", preset: true, presetValue: "Default value", - popFunc: server.ZPOPMIN, + popFunc: server.ZPopMin, key: "key5", count: 1, want: [][]string{}, @@ -1975,7 +1975,7 @@ func TestEchoVault_ZRANDMEMBER(t *testing.T) { return } } - got, err := server.ZRANDMEMBER(tt.key, tt.count, tt.withscores) + got, err := server.ZRandMember(tt.key, tt.count, tt.withscores) if (err != nil) != tt.wantErr { t.Errorf("ZRANDMEMBER() error = %v, wantErr %v", err, tt.wantErr) return @@ -1997,7 +1997,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key string start string stop string - options echovault.ZRANGEOptions + options echovault.ZRangeOptions want map[string]float64 wantErr bool }{ @@ -2013,7 +2013,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key: "key1", start: "3", stop: "7", - options: echovault.ZRANGEOptions{ByScore: true}, + options: echovault.ZRangeOptions{ByScore: true}, want: map[string]float64{"three": 0, "four": 0, "five": 0, "six": 0, "seven": 0}, wantErr: false, }, @@ -2029,7 +2029,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key: "key2", start: "3", stop: "7", - options: echovault.ZRANGEOptions{ByScore: true, WithScores: true}, + options: echovault.ZRangeOptions{ByScore: true, WithScores: true}, want: map[string]float64{"three": 3, "four": 4, "five": 5, "six": 6, "seven": 7}, wantErr: false, }, @@ -2047,7 +2047,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key: "key3", start: "3", stop: "7", - options: echovault.ZRANGEOptions{WithScores: true, ByScore: true, Offset: 2, Count: 4}, + options: echovault.ZRangeOptions{WithScores: true, ByScore: true, Offset: 2, Count: 4}, want: map[string]float64{"three": 3, "four": 4, "five": 5}, wantErr: false, }, @@ -2063,7 +2063,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key: "key4", start: "c", stop: "g", - options: echovault.ZRANGEOptions{ByLex: true}, + options: echovault.ZRangeOptions{ByLex: true}, want: map[string]float64{"c": 0, "d": 0, "e": 0, "f": 0, "g": 0}, wantErr: false, }, @@ -2079,7 +2079,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key: "key5", start: "a", stop: "f", - options: echovault.ZRANGEOptions{ByLex: true, WithScores: true}, + options: echovault.ZRangeOptions{ByLex: true, WithScores: true}, want: map[string]float64{"a": 1, "b": 1, "c": 1, "d": 1, "e": 1, "f": 1}, wantErr: false, }, @@ -2097,7 +2097,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key: "key6", start: "a", stop: "h", - options: echovault.ZRANGEOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, + options: echovault.ZRangeOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, want: map[string]float64{"c": 1, "d": 1, "e": 1}, wantErr: false, }, @@ -2113,7 +2113,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key: "key7", start: "a", stop: "h", - options: echovault.ZRANGEOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, + options: echovault.ZRangeOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, want: map[string]float64{}, wantErr: false, }, @@ -2124,7 +2124,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { key: "key10", start: "a", stop: "h", - options: echovault.ZRANGEOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, + options: echovault.ZRangeOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, want: nil, wantErr: true, }, @@ -2138,7 +2138,7 @@ func TestEchoVault_ZRANGE(t *testing.T) { return } } - got, err := server.ZRANGE(tt.key, tt.start, tt.stop, tt.options) + got, err := server.ZRange(tt.key, tt.start, tt.stop, tt.options) if (err != nil) != tt.wantErr { t.Errorf("ZRANGE() error = %v, wantErr %v", err, tt.wantErr) return @@ -2161,7 +2161,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source string start string stop string - options echovault.ZRANGESTOREOptions + options echovault.ZRangeStoreOptions want int wantErr bool }{ @@ -2180,7 +2180,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key1", start: "3", stop: "7", - options: echovault.ZRANGESTOREOptions{ByScore: true}, + options: echovault.ZRangeStoreOptions{ByScore: true}, want: 5, wantErr: false, }, @@ -2199,7 +2199,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key2", start: "3", stop: "7", - options: echovault.ZRANGESTOREOptions{WithScores: true, ByScore: true}, + options: echovault.ZRangeStoreOptions{WithScores: true, ByScore: true}, want: 5, wantErr: false, }, @@ -2220,7 +2220,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key3", start: "3", stop: "7", - options: echovault.ZRANGESTOREOptions{ByScore: true, WithScores: true, Offset: 2, Count: 4}, + options: echovault.ZRangeStoreOptions{ByScore: true, WithScores: true, Offset: 2, Count: 4}, want: 3, wantErr: false, }, @@ -2239,7 +2239,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key4", start: "c", stop: "g", - options: echovault.ZRANGESTOREOptions{ByLex: true}, + options: echovault.ZRangeStoreOptions{ByLex: true}, want: 5, wantErr: false, }, @@ -2258,7 +2258,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key5", start: "a", stop: "f", - options: echovault.ZRANGESTOREOptions{ByLex: true, WithScores: true}, + options: echovault.ZRangeStoreOptions{ByLex: true, WithScores: true}, want: 6, wantErr: false, }, @@ -2279,7 +2279,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key6", start: "a", stop: "h", - options: echovault.ZRANGESTOREOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, + options: echovault.ZRangeStoreOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, want: 3, wantErr: false, }, @@ -2301,7 +2301,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key7", start: "a", stop: "h", - options: echovault.ZRANGESTOREOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, + options: echovault.ZRangeStoreOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, want: 3, wantErr: false, }, @@ -2320,7 +2320,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key8", start: "a", stop: "h", - options: echovault.ZRANGESTOREOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, + options: echovault.ZRangeStoreOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, want: 0, wantErr: false, }, @@ -2334,7 +2334,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { source: "key9", start: "a", stop: "h", - options: echovault.ZRANGESTOREOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, + options: echovault.ZRangeStoreOptions{WithScores: true, ByLex: true, Offset: 2, Count: 4}, want: 0, wantErr: true, }, @@ -2350,7 +2350,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) { } } } - got, err := server.ZRANGESTORE(tt.destination, tt.source, tt.start, tt.stop, tt.options) + got, err := server.ZRangeStore(tt.destination, tt.source, tt.start, tt.stop, tt.options) if (err != nil) != tt.wantErr { t.Errorf("ZRANGESTORE() error = %v, wantErr %v", err, tt.wantErr) return @@ -2447,7 +2447,7 @@ func TestEchoVault_ZRANK(t *testing.T) { return } } - got, err := server.ZRANK(tt.key, tt.member, tt.withscores) + got, err := server.ZRank(tt.key, tt.member, tt.withscores) if (err != nil) != tt.wantErr { t.Errorf("ZRANK() error = %v, wantErr %v", err, tt.wantErr) return @@ -2516,7 +2516,7 @@ func TestEchoVault_ZREM(t *testing.T) { return } } - got, err := server.ZREM(tt.key, tt.members...) + got, err := server.ZRem(tt.key, tt.members...) if (err != nil) != tt.wantErr { t.Errorf("ZREM() error = %v, wantErr %v", err, tt.wantErr) return @@ -2586,7 +2586,7 @@ func TestEchoVault_ZREMRANGEBYSCORE(t *testing.T) { return } } - got, err := server.ZREMRANGEBYSCORE(tt.key, tt.min, tt.max) + got, err := server.ZRemRangeByScore(tt.key, tt.min, tt.max) if (err != nil) != tt.wantErr { t.Errorf("ZREMRANGEBYSCORE() error = %v, wantErr %v", err, tt.wantErr) return @@ -2664,7 +2664,7 @@ func TestEchoVault_ZSCORE(t *testing.T) { return } } - got, err := server.ZSCORE(tt.key, tt.member) + got, err := server.ZScore(tt.key, tt.member) if (err != nil) != tt.wantErr { t.Errorf("ZSCORE() error = %v, wantErr %v", err, tt.wantErr) return @@ -2684,7 +2684,7 @@ func TestEchoVault_ZUNION(t *testing.T) { preset bool presetValues map[string]interface{} keys []string - options echovault.ZUNIONOptions + options echovault.ZUnionOptions want map[string]float64 wantErr bool }{ @@ -2704,7 +2704,7 @@ func TestEchoVault_ZUNION(t *testing.T) { }), }, keys: []string{"key1", "key2"}, - options: echovault.ZUNIONOptions{}, + options: echovault.ZUnionOptions{}, want: map[string]float64{ "one": 0, "two": 0, "three": 0, "four": 0, "five": 0, "six": 0, "seven": 0, "eight": 0, @@ -2735,7 +2735,7 @@ func TestEchoVault_ZUNION(t *testing.T) { }), }, keys: []string{"key3", "key4", "key5"}, - options: echovault.ZUNIONOptions{WithScores: true}, + options: echovault.ZUnionOptions{WithScores: true}, want: map[string]float64{ "one": 3, "two": 4, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 24, "nine": 9, "ten": 10, "eleven": 11, "twelve": 24, "thirty-six": 72, @@ -2766,7 +2766,7 @@ func TestEchoVault_ZUNION(t *testing.T) { }), }, keys: []string{"key6", "key7", "key8"}, - options: echovault.ZUNIONOptions{WithScores: true, Aggregate: "MIN"}, + options: echovault.ZUnionOptions{WithScores: true, Aggregate: "MIN"}, want: map[string]float64{ "one": 1, "two": 2, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 8, "nine": 9, "ten": 10, "eleven": 11, "twelve": 12, "thirty-six": 36, @@ -2797,7 +2797,7 @@ func TestEchoVault_ZUNION(t *testing.T) { }), }, keys: []string{"key9", "key10", "key11"}, - options: echovault.ZUNIONOptions{WithScores: true, Aggregate: "MAX"}, + options: echovault.ZUnionOptions{WithScores: true, Aggregate: "MAX"}, want: map[string]float64{ "one": 1000, "two": 2, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 800, "nine": 9, "ten": 10, "eleven": 11, "twelve": 12, "thirty-six": 72, @@ -2828,7 +2828,7 @@ func TestEchoVault_ZUNION(t *testing.T) { }), }, keys: []string{"key12", "key13", "key14"}, - options: echovault.ZUNIONOptions{WithScores: true, Aggregate: "SUM", Weights: []float64{1, 2, 3}}, + options: echovault.ZUnionOptions{WithScores: true, Aggregate: "SUM", Weights: []float64{1, 2, 3}}, want: map[string]float64{ "one": 3102, "two": 6, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 2568, "nine": 27, "ten": 30, "eleven": 22, "twelve": 60, "thirty-six": 72, @@ -2859,7 +2859,7 @@ func TestEchoVault_ZUNION(t *testing.T) { }), }, keys: []string{"key15", "key16", "key17"}, - options: echovault.ZUNIONOptions{WithScores: true, Aggregate: "MAX", Weights: []float64{1, 2, 3}}, + options: echovault.ZUnionOptions{WithScores: true, Aggregate: "MAX", Weights: []float64{1, 2, 3}}, want: map[string]float64{ "one": 3000, "two": 4, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 2400, "nine": 27, "ten": 30, "eleven": 22, "twelve": 36, "thirty-six": 72, @@ -2890,7 +2890,7 @@ func TestEchoVault_ZUNION(t *testing.T) { }), }, keys: []string{"key18", "key19", "key20"}, - options: echovault.ZUNIONOptions{WithScores: true, Aggregate: "MIN", Weights: []float64{1, 2, 3}}, + options: echovault.ZUnionOptions{WithScores: true, Aggregate: "MIN", Weights: []float64{1, 2, 3}}, want: map[string]float64{ "one": 2, "two": 2, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 8, "nine": 27, "ten": 30, "eleven": 22, "twelve": 24, "thirty-six": 72, @@ -2910,7 +2910,7 @@ func TestEchoVault_ZUNION(t *testing.T) { "key22": ss.NewSortedSet([]ss.MemberParam{{Value: "one", Score: 1}}), }, keys: []string{"key21", "key22"}, - options: echovault.ZUNIONOptions{Weights: []float64{1, 2, 3}}, + options: echovault.ZUnionOptions{Weights: []float64{1, 2, 3}}, want: nil, wantErr: true, }, @@ -2930,7 +2930,7 @@ func TestEchoVault_ZUNION(t *testing.T) { "key25": ss.NewSortedSet([]ss.MemberParam{{Value: "one", Score: 1}}), }, keys: []string{"key23", "key24", "key25"}, - options: echovault.ZUNIONOptions{Weights: []float64{5, 4}}, + options: echovault.ZUnionOptions{Weights: []float64{5, 4}}, want: nil, wantErr: true, }, @@ -2943,7 +2943,7 @@ func TestEchoVault_ZUNION(t *testing.T) { "key28": ss.NewSortedSet([]ss.MemberParam{{Value: "one", Score: 1}}), }, keys: []string{}, - options: echovault.ZUNIONOptions{Weights: []float64{5, 4}}, + options: echovault.ZUnionOptions{Weights: []float64{5, 4}}, want: nil, wantErr: true, }, @@ -2961,7 +2961,7 @@ func TestEchoVault_ZUNION(t *testing.T) { "key31": ss.NewSortedSet([]ss.MemberParam{{Value: "one", Score: 1}}), }, keys: []string{"key29", "key30", "key31"}, - options: echovault.ZUNIONOptions{}, + options: echovault.ZUnionOptions{}, want: nil, wantErr: true, }, @@ -2981,7 +2981,7 @@ func TestEchoVault_ZUNION(t *testing.T) { }), }, keys: []string{"non-existent", "key32", "key33"}, - options: echovault.ZUNIONOptions{}, + options: echovault.ZUnionOptions{}, want: map[string]float64{ "one": 0, "two": 0, "thirty-six": 0, "twelve": 0, "eleven": 0, "seven": 0, "eight": 0, "nine": 0, "ten": 0, @@ -3000,7 +3000,7 @@ func TestEchoVault_ZUNION(t *testing.T) { } } } - got, err := server.ZUNION(tt.keys, tt.options) + got, err := server.ZUnion(tt.keys, tt.options) if (err != nil) != tt.wantErr { t.Errorf("ZUNION() error = %v, wantErr %v", err, tt.wantErr) return @@ -3021,7 +3021,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { presetValues map[string]interface{} destination string keys []string - options echovault.ZUNIONSTOREOptions + options echovault.ZUnionStoreOptions want int wantErr bool }{ @@ -3042,7 +3042,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination1", keys: []string{"key1", "key2"}, - options: echovault.ZUNIONSTOREOptions{}, + options: echovault.ZUnionStoreOptions{}, want: 8, wantErr: false, }, @@ -3071,7 +3071,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination2", keys: []string{"key3", "key4", "key5"}, - options: echovault.ZUNIONSTOREOptions{WithScores: true}, + options: echovault.ZUnionStoreOptions{WithScores: true}, want: 13, wantErr: false, }, @@ -3100,7 +3100,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination3", keys: []string{"key6", "key7", "key8"}, - options: echovault.ZUNIONSTOREOptions{WithScores: true, Aggregate: "MIN"}, + options: echovault.ZUnionStoreOptions{WithScores: true, Aggregate: "MIN"}, want: 13, wantErr: false, }, @@ -3129,7 +3129,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination4", keys: []string{"key9", "key10", "key11"}, - options: echovault.ZUNIONSTOREOptions{WithScores: true, Aggregate: "MAX"}, + options: echovault.ZUnionStoreOptions{WithScores: true, Aggregate: "MAX"}, want: 13, wantErr: false, }, @@ -3158,7 +3158,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination5", keys: []string{"key12", "key13", "key14"}, - options: echovault.ZUNIONSTOREOptions{WithScores: true, Aggregate: "SUM", Weights: []float64{1, 2, 3}}, + options: echovault.ZUnionStoreOptions{WithScores: true, Aggregate: "SUM", Weights: []float64{1, 2, 3}}, want: 13, wantErr: false, }, @@ -3187,7 +3187,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination6", keys: []string{"key15", "key16", "key17"}, - options: echovault.ZUNIONSTOREOptions{WithScores: true, Aggregate: "MAX", Weights: []float64{1, 2, 3}}, + options: echovault.ZUnionStoreOptions{WithScores: true, Aggregate: "MAX", Weights: []float64{1, 2, 3}}, want: 13, wantErr: false, }, @@ -3216,7 +3216,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination7", keys: []string{"destination7", "key18", "key19", "key20"}, - options: echovault.ZUNIONSTOREOptions{WithScores: true, Aggregate: "MIN", Weights: []float64{1, 2, 3}}, + options: echovault.ZUnionStoreOptions{WithScores: true, Aggregate: "MIN", Weights: []float64{1, 2, 3}}, want: 13, wantErr: false, }, @@ -3234,7 +3234,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination8", keys: []string{"key21", "key22"}, - options: echovault.ZUNIONSTOREOptions{Weights: []float64{1, 2, 3}}, + options: echovault.ZUnionStoreOptions{Weights: []float64{1, 2, 3}}, want: 0, wantErr: true, }, @@ -3255,7 +3255,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination9", keys: []string{"key23", "key24", "key25"}, - options: echovault.ZUNIONSTOREOptions{Weights: []float64{5, 4}}, + options: echovault.ZUnionStoreOptions{Weights: []float64{5, 4}}, want: 0, wantErr: true, }, @@ -3274,7 +3274,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { }, destination: "destination11", keys: []string{"key29", "key30", "key31"}, - options: echovault.ZUNIONSTOREOptions{}, + options: echovault.ZUnionStoreOptions{}, want: 0, wantErr: true, }, @@ -3310,7 +3310,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) { } } } - got, err := server.ZUNIONSTORE(tt.destination, tt.keys, tt.options) + got, err := server.ZUnionStore(tt.destination, tt.keys, tt.options) if (err != nil) != tt.wantErr { t.Errorf("ZUNIONSTORE() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/test/modules/sorted_set/commands_test.go b/test/modules/sorted_set/commands_test.go index bdf233ed..0ae5a4c8 100644 --- a/test/modules/sorted_set/commands_test.go +++ b/test/modules/sorted_set/commands_test.go @@ -19,11 +19,11 @@ import ( "context" "errors" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" + "github.com/echovault/echovault/internal/constants" "github.com/echovault/echovault/internal/modules/sorted_set" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" "github.com/tidwall/resp" "math" "net" diff --git a/test/modules/string/api_test.go b/test/modules/string/api_test.go index 6bb96f47..8fad7c03 100644 --- a/test/modules/string/api_test.go +++ b/test/modules/string/api_test.go @@ -16,8 +16,8 @@ package str import ( "context" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/echovault" "testing" ) @@ -57,7 +57,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { { name: "Return substring within the range of the string", key: "key1", - substrFunc: server.SUBSTR, + substrFunc: server.SubStr, presetValue: "Test String One", start: 5, end: 10, @@ -67,7 +67,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { { name: "Return substring at the end of the string with exact end index", key: "key2", - substrFunc: server.SUBSTR, + substrFunc: server.SubStr, presetValue: "Test String Two", start: 12, end: 14, @@ -77,7 +77,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { { name: "Return substring at the end of the string with end index greater than length", key: "key3", - substrFunc: server.SUBSTR, + substrFunc: server.SubStr, presetValue: "Test String Three", start: 12, end: 75, @@ -86,7 +86,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { { name: "Return the substring at the start of the string with 0 start index", key: "key4", - substrFunc: server.SUBSTR, + substrFunc: server.SubStr, presetValue: "Test String Four", start: 0, end: 3, @@ -98,7 +98,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { // Substring should begin abs(start) from the end of the string when start is negative. name: "Return the substring with negative start index", key: "key5", - substrFunc: server.SUBSTR, + substrFunc: server.SubStr, presetValue: "Test String Five", start: -11, end: 10, @@ -110,7 +110,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { // When end index is smaller than start index, the 2 indices are reversed. name: "Return reverse substring with end index smaller than start index", key: "key6", - substrFunc: server.SUBSTR, + substrFunc: server.SubStr, presetValue: "Test String Six", start: 4, end: 0, @@ -119,7 +119,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { { name: "Return substring within the range of the string", key: "key7", - substrFunc: server.GETRANGE, + substrFunc: server.GetRange, presetValue: "Test String One", start: 5, end: 10, @@ -129,7 +129,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { { name: "Return substring at the end of the string with exact end index", key: "key8", - substrFunc: server.GETRANGE, + substrFunc: server.GetRange, presetValue: "Test String Two", start: 12, end: 14, @@ -139,7 +139,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { { name: "Return substring at the end of the string with end index greater than length", key: "key9", - substrFunc: server.GETRANGE, + substrFunc: server.GetRange, presetValue: "Test String Three", start: 12, end: 75, @@ -148,7 +148,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { { name: "Return the substring at the start of the string with 0 start index", key: "key10", - substrFunc: server.GETRANGE, + substrFunc: server.GetRange, presetValue: "Test String Four", start: 0, end: 3, @@ -160,7 +160,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { // Substring should begin abs(start) from the end of the string when start is negative. name: "Return the substring with negative start index", key: "key11", - substrFunc: server.GETRANGE, + substrFunc: server.GetRange, presetValue: "Test String Five", start: -11, end: 10, @@ -172,7 +172,7 @@ func TestEchoVault_SUBSTR(t *testing.T) { // When end index is smaller than start index, the 2 indices are reversed. name: "Return reverse substring with end index smaller than start index", key: "key12", - substrFunc: server.GETRANGE, + substrFunc: server.GetRange, presetValue: "Test String Six", start: 4, end: 0, @@ -276,7 +276,7 @@ func TestEchoVault_SETRANGE(t *testing.T) { return } } - got, err := server.SETRANGE(tt.key, tt.offset, tt.new) + got, err := server.SetRange(tt.key, tt.offset, tt.new) if (err != nil) != tt.wantErr { t.Errorf("SETRANGE() error = %v, wantErr %v", err, tt.wantErr) return @@ -322,7 +322,7 @@ func TestEchoVault_STRLEN(t *testing.T) { return } } - got, err := server.STRLEN(tt.key) + got, err := server.StrLen(tt.key) if (err != nil) != tt.wantErr { t.Errorf("STRLEN() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/test/modules/string/commands_test.go b/test/modules/string/commands_test.go index 5eac8292..b92aba0d 100644 --- a/test/modules/string/commands_test.go +++ b/test/modules/string/commands_test.go @@ -19,10 +19,10 @@ import ( "context" "errors" "fmt" + "github.com/echovault/echovault/echovault" "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" - "github.com/echovault/echovault/pkg/constants" - "github.com/echovault/echovault/pkg/echovault" + "github.com/echovault/echovault/internal/constants" "github.com/tidwall/resp" "net" "reflect" diff --git a/types/types.go b/types/types.go new file mode 100644 index 00000000..2e421b60 --- /dev/null +++ b/types/types.go @@ -0,0 +1,100 @@ +// Copyright 2024 Kelvin Clement Mwinuka +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "context" + "net" + "time" +) + +type EchoVault interface { + KeyLock(ctx context.Context, key string) (bool, error) + KeyUnlock(ctx context.Context, key string) + KeyRLock(ctx context.Context, key string) (bool, error) + KeyRUnlock(ctx context.Context, key string) + KeyExists(ctx context.Context, key string) bool + CreateKeyAndLock(ctx context.Context, key string) (bool, error) + GetValue(ctx context.Context, key string) interface{} + SetValue(ctx context.Context, key string, value interface{}) error + GetExpiry(ctx context.Context, key string) time.Time + SetExpiry(ctx context.Context, key string, expire time.Time, touch bool) + RemoveExpiry(ctx context.Context, key string) + DeleteKey(ctx context.Context, key string) error +} + +// CommandKeyExtractionFuncResult specifies the keys accessed by the associated command or subcommand. +// ReadKeys is a string slice containing the keys that the commands read from. +// WriteKeys is a string slice containing the keys that the command writes to. +// +// These keys will typically be extracted from the command slice, but they can also be hardcoded. +type CommandKeyExtractionFuncResult struct { + ReadKeys []string + WriteKeys []string +} + +// CommandKeyExtractionFunc if the function that extracts the keys accessed by the command or subcommand. +type CommandKeyExtractionFunc func(cmd []string) (CommandKeyExtractionFuncResult, error) + +// CommandHandlerFunc is the handler function for the command or subcommand. +// +// This function must return a byte slice containing a valid RESP2 response, or an error. +type CommandHandlerFunc func(params CommandHandlerFuncParams) ([]byte, error) + +// CommandHandlerFuncParams contains the helper parameters passed to the command's handler by EchoVault. +// +// Command is the string slice command containing the command that triggered this handler. +// +// Connection is the TCP connection that triggered this command. In embedded mode, this will always be nil. +// Any TCP client that trigger the custom command will have its connection passed to the handler here. +// +// KeyExists returns true if the key passed to it exists in the store. +// +// CreateKeyAndLock creates the new key and immediately write locks it. If the key already exists, then +// it is simply write locked which makes this function safe to call even if the key already exists. Always call +// KeyUnlock when done after CreateKeyAndLock. +// +// KeyLock acquires a write lock for the specified key. If the lock is successfully acquired, the function will return +// (true, nil). Otherwise, it will return false and an error describing why the locking failed. Always call KeyUnlock +// when done after KeyLock. +// +// KeyUnlock releases the write lock for the specified key. Always call this after KeyLock otherwise the key will not be +// lockable by any future invocations of this command or other commands. +// +// KeyRLock acquires a read lock for the specified key. If the lock is successfully acquired, the function will return +// (true, nil). Otherwise, it will return false and an error describing why the locking failed. Always call KeyRUnlock +// when done after KeyRLock. +// +// KeyRUnlock releases the real lock for the specified key. Always call this after KeyRLock otherwise the key will not be +// write-lockable by any future invocations of this command or other commands. +// +// GetValue returns the value held at the specified key as an interface{}. Make sure to invoke KeyLock or KeyRLock on the +// key before GetValue to ensure thread safety. +// +// SetValue sets the value at the specified key. Make sure to invoke KeyLock on the key before +// SetValue to ensure thread safety. +type CommandHandlerFuncParams struct { + Context context.Context + Command []string + Connection *net.Conn + KeyExists func(ctx context.Context, key string) bool + CreateKeyAndLock func(ctx context.Context, key string) (bool, error) + KeyLock func(ctx context.Context, key string) (bool, error) + KeyUnlock func(ctx context.Context, key string) + KeyRLock func(ctx context.Context, key string) (bool, error) + KeyRUnlock func(ctx context.Context, key string) + GetValue func(ctx context.Context, key string) interface{} + SetValue func(ctx context.Context, key string, value interface{}) error +}