Created 'constants' package for const.go file and 'types' package for shared and exported types

This commit is contained in:
Kelvin Mwinuka
2024-04-01 18:32:01 +08:00
parent 4010306dee
commit d7c3509533
43 changed files with 2927 additions and 2913 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"github.com/gobwas/glob" "github.com/gobwas/glob"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"log" "log"
@@ -285,7 +286,7 @@ func (acl *ACL) AuthenticateConnection(_ context.Context, conn *net.Conn, cmd []
return errors.New("could not authenticate user") return errors.New("could not authenticate user")
} }
func (acl *ACL) AuthorizeConnection(conn *net.Conn, cmd []string, command utils.Command, subCommand utils.SubCommand) error { func (acl *ACL) AuthorizeConnection(conn *net.Conn, cmd []string, command types.Command, subCommand types.SubCommand) error {
acl.RLockUsers() acl.RLockUsers()
defer acl.RUnlockUsers() defer acl.RUnlockUsers()
@@ -298,7 +299,7 @@ func (acl *ACL) AuthorizeConnection(conn *net.Conn, cmd []string, command utils.
return err return err
} }
if !reflect.DeepEqual(subCommand, utils.SubCommand{}) { if !reflect.DeepEqual(subCommand, types.SubCommand{}) {
comm = fmt.Sprintf("%s|%s", comm, subCommand.Command) comm = fmt.Sprintf("%s|%s", comm, subCommand.Command)
categories = append(categories, subCommand.Categories...) categories = append(categories, subCommand.Categories...)
keys, err = subCommand.KeyExtractionFunc(cmd) keys, err = subCommand.KeyExtractionFunc(cmd)
@@ -380,7 +381,7 @@ func (acl *ACL) AuthorizeConnection(conn *net.Conn, cmd []string, command utils.
} }
// 6. PUBSUB authorisation. // 6. PUBSUB authorisation.
if slices.Contains(categories, utils.PubSubCategory) { if slices.Contains(categories, constants.PubSubCategory) {
// In PUBSUB, KeyExtractionFunc returns channels so keys[0] is aliased to channel // In PUBSUB, KeyExtractionFunc returns channels so keys[0] is aliased to channel
channel := keys[0] channel := keys[0]
// 2.1) Check if the channel is in IncludedPubSubChannels // 2.1) Check if the channel is in IncludedPubSubChannels
@@ -405,7 +406,7 @@ func (acl *ACL) AuthorizeConnection(conn *net.Conn, cmd []string, command utils.
} }
// 8. If @read is in the list of categories, check if keys are in IncludedReadKeys // 8. If @read is in the list of categories, check if keys are in IncludedReadKeys
if slices.Contains(categories, utils.ReadCategory) { if slices.Contains(categories, constants.ReadCategory) {
if !slices.ContainsFunc(keys, func(key string) bool { if !slices.ContainsFunc(keys, func(key string) bool {
return slices.ContainsFunc(connection.User.IncludedReadKeys, func(readKeyGlob string) bool { return slices.ContainsFunc(connection.User.IncludedReadKeys, func(readKeyGlob string) bool {
if acl.GlobPatterns[readKeyGlob].Match(key) { if acl.GlobPatterns[readKeyGlob].Match(key) {
@@ -420,7 +421,7 @@ func (acl *ACL) AuthorizeConnection(conn *net.Conn, cmd []string, command utils.
} }
// 9. If @write is in the list of categories, check if keys are in IncludedWriteKeys // 9. If @write is in the list of categories, check if keys are in IncludedWriteKeys
if slices.Contains(categories, utils.WriteCategory) { if slices.Contains(categories, constants.WriteCategory) {
if !slices.ContainsFunc(keys, func(key string) bool { if !slices.ContainsFunc(keys, func(key string) bool {
return slices.ContainsFunc(connection.User.IncludedWriteKeys, func(writeKeyGlob string) bool { return slices.ContainsFunc(connection.User.IncludedWriteKeys, func(writeKeyGlob string) bool {
if acl.GlobPatterns[writeKeyGlob].Match(key) { if acl.GlobPatterns[writeKeyGlob].Match(key) {

View File

@@ -20,7 +20,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"log" "log"
"os" "os"
"path" "path"
@@ -108,7 +108,7 @@ There is no limit by default.`, func(memory string) error {
return nil return nil
}) })
evictionPolicy := utils.NoEviction evictionPolicy := constants.NoEviction
flag.Func("eviction-policy", `The eviction policy used to remove keys when max-memory is reached. The options are: flag.Func("eviction-policy", `The eviction policy used to remove keys when max-memory is reached. The options are:
1) noeviction - Do not evict any keys even when max-memory is exceeded. 1) noeviction - Do not evict any keys even when max-memory is exceeded.
2) allkeys-lfu - Evict the least frequently used keys. 2) allkeys-lfu - Evict the least frequently used keys.
@@ -118,9 +118,9 @@ There is no limit by default.`, func(memory string) error {
6) allkeys-random - Evict random keys until we get under the max-memory limit. 6) allkeys-random - Evict random keys until we get under the max-memory limit.
7) volatile-random - Evict random keys with an expiration.`, func(policy string) error { 7) volatile-random - Evict random keys with an expiration.`, func(policy string) error {
policies := []string{ policies := []string{
utils.NoEviction, constants.NoEviction,
utils.AllKeysLFU, utils.AllKeysLRU, utils.AllKeysRandom, constants.AllKeysLFU, constants.AllKeysLRU, constants.AllKeysRandom,
utils.VolatileLFU, utils.VolatileLRU, utils.VolatileRandom, constants.VolatileLFU, constants.VolatileLRU, constants.VolatileRandom,
} }
policyIdx := slices.Index(policies, strings.ToLower(policy)) policyIdx := slices.Index(policies, strings.ToLower(policy))
if policyIdx == -1 { if policyIdx == -1 {

View File

@@ -1,7 +1,7 @@
package config package config
import ( import (
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"time" "time"
) )
@@ -30,7 +30,7 @@ func DefaultConfig() Config {
RestoreSnapshot: false, RestoreSnapshot: false,
AOFSyncStrategy: "everysec", AOFSyncStrategy: "everysec",
MaxMemory: 0, MaxMemory: 0,
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
EvictionSample: 20, EvictionSample: 20,
EvictionInterval: 100 * time.Millisecond, EvictionInterval: 100 * time.Millisecond,
} }

View File

@@ -20,7 +20,7 @@ import (
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/types"
"github.com/hashicorp/raft" "github.com/hashicorp/raft"
"io" "io"
"log" "log"
@@ -29,9 +29,9 @@ import (
type FSMOpts struct { type FSMOpts struct {
Config config.Config Config config.Config
EchoVault utils.EchoVault EchoVault types.EchoVault
GetState func() map[string]internal.KeyData GetState func() map[string]internal.KeyData
GetCommand func(command string) (utils.Command, error) GetCommand func(command string) (types.Command, error)
DeleteKey func(ctx context.Context, key string) error DeleteKey func(ctx context.Context, key string) error
} }
@@ -94,7 +94,7 @@ func (fsm *FSM) Apply(log *raft.Log) interface{} {
handler := command.HandlerFunc handler := command.HandlerFunc
subCommand, ok := internal.GetSubCommand(command, request.CMD).(utils.SubCommand) subCommand, ok := internal.GetSubCommand(command, request.CMD).(types.SubCommand)
if ok { if ok {
handler = subCommand.HandlerFunc handler = subCommand.HandlerFunc
} }

View File

@@ -27,16 +27,16 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/types"
"github.com/hashicorp/raft" "github.com/hashicorp/raft"
raftboltdb "github.com/hashicorp/raft-boltdb" raftboltdb "github.com/hashicorp/raft-boltdb"
) )
type Opts struct { type Opts struct {
Config config.Config Config config.Config
EchoVault utils.EchoVault EchoVault types.EchoVault
GetState func() map[string]internal.KeyData GetState func() map[string]internal.KeyData
GetCommand func(command string) (utils.Command, error) GetCommand func(command string) (types.Command, error)
DeleteKey func(ctx context.Context, key string) error DeleteKey func(ctx context.Context, key string) error
} }

View File

@@ -20,7 +20,8 @@ import (
"cmp" "cmp"
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"io" "io"
"log" "log"
"math/big" "math/big"
@@ -128,7 +129,7 @@ func GetIPAddress() (string, error) {
return localAddr, nil return localAddr, nil
} }
func GetSubCommand(command utils.Command, cmd []string) interface{} { func GetSubCommand(command types.Command, cmd []string) interface{} {
if len(command.SubCommands) == 0 || len(cmd) < 2 { if len(command.SubCommands) == 0 || len(cmd) < 2 {
return nil return nil
} }
@@ -140,8 +141,8 @@ func GetSubCommand(command utils.Command, cmd []string) interface{} {
return nil return nil
} }
func IsWriteCommand(command utils.Command, subCommand utils.SubCommand) bool { func IsWriteCommand(command types.Command, subCommand types.SubCommand) bool {
return slices.Contains(append(command.Categories, subCommand.Categories...), utils.WriteCategory) return slices.Contains(append(command.Categories, subCommand.Categories...), constants.WriteCategory)
} }
func AbsInt(n int) int { func AbsInt(n int) int {

View File

@@ -11,12 +11,12 @@ import (
"github.com/echovault/echovault/pkg/modules/set" "github.com/echovault/echovault/pkg/modules/set"
"github.com/echovault/echovault/pkg/modules/sorted_set" "github.com/echovault/echovault/pkg/modules/sorted_set"
str "github.com/echovault/echovault/pkg/modules/string" str "github.com/echovault/echovault/pkg/modules/string"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/types"
) )
// All returns all the commands currently available on EchoVault // All returns all the commands currently available on EchoVault
func All() []utils.Command { func All() []types.Command {
var commands []utils.Command var commands []types.Command
commands = append(commands, acl.Commands()...) commands = append(commands, acl.Commands()...)
commands = append(commands, admin.Commands()...) commands = append(commands, admin.Commands()...)
commands = append(commands, generic.Commands()...) commands = append(commands, generic.Commands()...)

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package utils package constants
const ( const (
ACLModule = "acl" ACLModule = "acl"

View File

@@ -17,7 +17,7 @@ package echovault
import ( import (
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/commands" "github.com/echovault/echovault/pkg/commands"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"reflect" "reflect"
"slices" "slices"
"testing" "testing"
@@ -28,7 +28,7 @@ func TestEchoVault_HDEL(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -95,7 +95,7 @@ func TestEchoVault_HEXISTS(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -154,7 +154,7 @@ func TestEchoVault_HGETALL(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -216,7 +216,7 @@ func TestEchoVault_HINCRBY(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -330,7 +330,7 @@ func TestEchoVault_HKEYS(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -390,7 +390,7 @@ func TestEchoVault_HLEN(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -445,7 +445,7 @@ func TestEchoVault_HRANDFIELD(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -579,7 +579,7 @@ func TestEchoVault_HSET(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -669,7 +669,7 @@ func TestEchoVault_HSTRLEN(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -738,7 +738,7 @@ func TestEchoVault_HVALS(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )

View File

@@ -18,7 +18,7 @@ import (
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/commands" "github.com/echovault/echovault/pkg/commands"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"reflect" "reflect"
"testing" "testing"
) )
@@ -28,7 +28,7 @@ func TestEchoVault_LLEN(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -87,7 +87,7 @@ func TestEchoVault_LINDEX(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -187,7 +187,7 @@ func TestEchoVault_LMOVE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -359,7 +359,7 @@ func TestEchoVault_POP(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -431,7 +431,7 @@ func TestEchoVault_LPUSH(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -508,7 +508,7 @@ func TestEchoVault_RPUSH(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -565,7 +565,7 @@ func TestEchoVault_LRANGE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -686,7 +686,7 @@ func TestEchoVault_LREM(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -753,7 +753,7 @@ func TestEchoVault_LSET(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -860,7 +860,7 @@ func TestEchoVault_LTRIM(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )

View File

@@ -18,7 +18,7 @@ import (
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/internal/set" "github.com/echovault/echovault/internal/set"
"github.com/echovault/echovault/pkg/commands" "github.com/echovault/echovault/pkg/commands"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"reflect" "reflect"
"slices" "slices"
"testing" "testing"
@@ -29,7 +29,7 @@ func TestEchoVault_SADD(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -88,7 +88,7 @@ func TestEchoVault_SCARD(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -143,7 +143,7 @@ func TestEchoVault_SDIFF(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -237,7 +237,7 @@ func TestEchoVault_SDIFFSTORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -332,7 +332,7 @@ func TestEchoVault_SINTER(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -426,7 +426,7 @@ func TestEchoVault_SINTERCARD(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -532,7 +532,7 @@ func TestEchoVault_SINTERSTORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -627,7 +627,7 @@ func TestEchoVault_SISMEMBER(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -686,7 +686,7 @@ func TestEchoVault_SMEMBERS(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -746,7 +746,7 @@ func TestEchoVault_SMISMEMBER(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -824,7 +824,7 @@ func TestEchoVault_SMOVE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -910,7 +910,7 @@ func TestEchoVault_SPOP(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -963,7 +963,7 @@ func TestEchoVault_SRANDMEMBER(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1032,7 +1032,7 @@ func TestEchoVault_SREM(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1091,7 +1091,7 @@ func TestEchoVault_SUNION(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1178,7 +1178,7 @@ func TestEchoVault_SUNIONSTORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )

View File

@@ -19,7 +19,7 @@ import (
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/internal/sorted_set" "github.com/echovault/echovault/internal/sorted_set"
"github.com/echovault/echovault/pkg/commands" "github.com/echovault/echovault/pkg/commands"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"math" "math"
"reflect" "reflect"
"strconv" "strconv"
@@ -31,7 +31,7 @@ func TestEchoVault_ZADD(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -257,7 +257,7 @@ func TestEchoVault_ZCARD(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -320,7 +320,7 @@ func TestEchoVault_ZCOUNT(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -421,7 +421,7 @@ func TestEchoVault_ZDIFF(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -573,7 +573,7 @@ func TestEchoVault_ZDIFFSTORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -694,7 +694,7 @@ func TestEchoVault_ZINCRBY(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -844,7 +844,7 @@ func TestEchoVault_ZINTER(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1157,7 +1157,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1484,7 +1484,7 @@ func TestEchoVault_ZLEXCOUNT(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1577,7 +1577,7 @@ func TestEchoVault_ZMPOP(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1733,7 +1733,7 @@ func TestEchoVault_ZMSCORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1814,7 +1814,7 @@ func TestEchoVault_ZPOP(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1922,7 +1922,7 @@ func TestEchoVault_ZRANDMEMBER(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -1998,7 +1998,7 @@ func TestEchoVault_ZRANGE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -2163,7 +2163,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -2377,7 +2377,7 @@ func TestEchoVault_ZRANK(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -2476,7 +2476,7 @@ func TestEchoVault_ZREM(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -2547,7 +2547,7 @@ func TestEchoVault_ZREMRANGEBYSCORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -2619,7 +2619,7 @@ func TestEchoVault_ZSCORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -2699,7 +2699,7 @@ func TestEchoVault_ZUNION(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
@@ -3037,7 +3037,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) {
WithCommands(commands.All()), WithCommands(commands.All()),
WithConfig(config.Config{ WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )

View File

@@ -29,7 +29,8 @@ import (
"github.com/echovault/echovault/internal/pubsub" "github.com/echovault/echovault/internal/pubsub"
"github.com/echovault/echovault/internal/raft" "github.com/echovault/echovault/internal/raft"
"github.com/echovault/echovault/internal/snapshot" "github.com/echovault/echovault/internal/snapshot"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"io" "io"
"log" "log"
"net" "net"
@@ -69,7 +70,7 @@ type EchoVault struct {
} }
// Holds the list of all commands supported by the echovault. // Holds the list of all commands supported by the echovault.
commands []utils.Command commands []types.Command
raft *raft.Raft // The raft replication layer for the echovault. raft *raft.Raft // The raft replication layer for the echovault.
memberList *memberlist.MemberList // The memberlist layer for the echovault. memberList *memberlist.MemberList // The memberlist layer for the echovault.
@@ -100,7 +101,7 @@ func WithConfig(config config.Config) func(echovault *EchoVault) {
} }
} }
func WithCommands(commands []utils.Command) func(echovault *EchoVault) { func WithCommands(commands []types.Command) func(echovault *EchoVault) {
return func(echovault *EchoVault) { return func(echovault *EchoVault) {
echovault.commands = commands echovault.commands = commands
} }
@@ -109,7 +110,7 @@ func WithCommands(commands []utils.Command) func(echovault *EchoVault) {
func NewEchoVault(options ...func(echovault *EchoVault)) *EchoVault { func NewEchoVault(options ...func(echovault *EchoVault)) *EchoVault {
echovault := &EchoVault{ echovault := &EchoVault{
context: context.Background(), context: context.Background(),
commands: make([]utils.Command, 0), commands: make([]types.Command, 0),
config: config.DefaultConfig(), config: config.DefaultConfig(),
store: make(map[string]internal.KeyData), store: make(map[string]internal.KeyData),
keyLocks: make(map[string]*sync.RWMutex), keyLocks: make(map[string]*sync.RWMutex),
@@ -220,7 +221,7 @@ func NewEchoVault(options ...func(echovault *EchoVault)) *EchoVault {
} }
// If eviction policy is not noeviction, start a goroutine to evict keys every 100 milliseconds. // If eviction policy is not noeviction, start a goroutine to evict keys every 100 milliseconds.
if echovault.config.EvictionPolicy != utils.NoEviction { if echovault.config.EvictionPolicy != constants.NoEviction {
go func() { go func() {
for { for {
<-time.After(echovault.config.EvictionInterval) <-time.After(echovault.config.EvictionInterval)

View File

@@ -19,7 +19,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"log" "log"
"math/rand" "math/rand"
"runtime" "runtime"
@@ -128,7 +128,7 @@ func (server *EchoVault) KeyExists(ctx context.Context, key string) bool {
// CreateKeyAndLock creates a new key lock and immediately locks it if the key does not exist. // CreateKeyAndLock creates a new key lock and immediately locks it if the key does not exist.
// If the key exists, the existing key is locked. // If the key exists, the existing key is locked.
func (server *EchoVault) CreateKeyAndLock(ctx context.Context, key string) (bool, error) { func (server *EchoVault) CreateKeyAndLock(ctx context.Context, key string) (bool, error) {
if internal.IsMaxMemoryExceeded(server.config.MaxMemory) && server.config.EvictionPolicy == utils.NoEviction { if internal.IsMaxMemoryExceeded(server.config.MaxMemory) && server.config.EvictionPolicy == constants.NoEviction {
return false, errors.New("max memory reached, key not created") return false, errors.New("max memory reached, key not created")
} }
@@ -166,7 +166,7 @@ func (server *EchoVault) GetValue(ctx context.Context, key string) interface{} {
// This count triggers a snapshot when the threshold is reached. // This count triggers a snapshot when the threshold is reached.
// The key must be locked prior to calling this function. // The key must be locked prior to calling this function.
func (server *EchoVault) SetValue(ctx context.Context, key string, value interface{}) error { func (server *EchoVault) SetValue(ctx context.Context, key string, value interface{}) error {
if internal.IsMaxMemoryExceeded(server.config.MaxMemory) && server.config.EvictionPolicy == utils.NoEviction { if internal.IsMaxMemoryExceeded(server.config.MaxMemory) && server.config.EvictionPolicy == constants.NoEviction {
return errors.New("max memory reached, key value not set") return errors.New("max memory reached, key value not set")
} }
@@ -276,9 +276,9 @@ func (server *EchoVault) DeleteKey(ctx context.Context, key string) error {
// Remove the key from the cache. // Remove the key from the cache.
switch { switch {
case slices.Contains([]string{utils.AllKeysLFU, utils.VolatileLFU}, server.config.EvictionPolicy): case slices.Contains([]string{constants.AllKeysLFU, constants.VolatileLFU}, server.config.EvictionPolicy):
server.lfuCache.cache.Delete(key) server.lfuCache.cache.Delete(key)
case slices.Contains([]string{utils.AllKeysLRU, utils.VolatileLRU}, server.config.EvictionPolicy): case slices.Contains([]string{constants.AllKeysLRU, constants.VolatileLRU}, server.config.EvictionPolicy):
server.lruCache.cache.Delete(key) server.lruCache.cache.Delete(key)
} }
@@ -299,21 +299,21 @@ func (server *EchoVault) updateKeyInCache(ctx context.Context, key string) error
return nil return nil
} }
switch strings.ToLower(server.config.EvictionPolicy) { switch strings.ToLower(server.config.EvictionPolicy) {
case utils.AllKeysLFU: case constants.AllKeysLFU:
server.lfuCache.mutex.Lock() server.lfuCache.mutex.Lock()
defer server.lfuCache.mutex.Unlock() defer server.lfuCache.mutex.Unlock()
server.lfuCache.cache.Update(key) server.lfuCache.cache.Update(key)
case utils.AllKeysLRU: case constants.AllKeysLRU:
server.lruCache.mutex.Lock() server.lruCache.mutex.Lock()
defer server.lruCache.mutex.Unlock() defer server.lruCache.mutex.Unlock()
server.lruCache.cache.Update(key) server.lruCache.cache.Update(key)
case utils.VolatileLFU: case constants.VolatileLFU:
server.lfuCache.mutex.Lock() server.lfuCache.mutex.Lock()
defer server.lfuCache.mutex.Unlock() defer server.lfuCache.mutex.Unlock()
if server.store[key].ExpireAt != (time.Time{}) { if server.store[key].ExpireAt != (time.Time{}) {
server.lfuCache.cache.Update(key) server.lfuCache.cache.Update(key)
} }
case utils.VolatileLRU: case constants.VolatileLRU:
server.lruCache.mutex.Lock() server.lruCache.mutex.Lock()
defer server.lruCache.mutex.Unlock() defer server.lruCache.mutex.Unlock()
if server.store[key].ExpireAt != (time.Time{}) { if server.store[key].ExpireAt != (time.Time{}) {
@@ -350,7 +350,7 @@ func (server *EchoVault) adjustMemoryUsage(ctx context.Context) error {
// Start a loop that evicts keys until either the heap is empty or // Start a loop that evicts keys until either the heap is empty or
// we're below the max memory limit. // we're below the max memory limit.
switch { switch {
case slices.Contains([]string{utils.AllKeysLFU, utils.VolatileLFU}, strings.ToLower(server.config.EvictionPolicy)): case slices.Contains([]string{constants.AllKeysLFU, constants.VolatileLFU}, strings.ToLower(server.config.EvictionPolicy)):
// Remove keys from LFU cache until we're below the max memory limit or // Remove keys from LFU cache until we're below the max memory limit or
// until the LFU cache is empty. // until the LFU cache is empty.
server.lfuCache.mutex.Lock() server.lfuCache.mutex.Lock()
@@ -382,7 +382,7 @@ func (server *EchoVault) adjustMemoryUsage(ctx context.Context) error {
return nil return nil
} }
} }
case slices.Contains([]string{utils.AllKeysLRU, utils.VolatileLRU}, strings.ToLower(server.config.EvictionPolicy)): case slices.Contains([]string{constants.AllKeysLRU, constants.VolatileLRU}, strings.ToLower(server.config.EvictionPolicy)):
// Remove keys from th LRU cache until we're below the max memory limit or // Remove keys from th LRU cache until we're below the max memory limit or
// until the LRU cache is empty. // until the LRU cache is empty.
server.lruCache.mutex.Lock() server.lruCache.mutex.Lock()
@@ -415,7 +415,7 @@ func (server *EchoVault) adjustMemoryUsage(ctx context.Context) error {
return nil return nil
} }
} }
case slices.Contains([]string{utils.AllKeysRandom}, strings.ToLower(server.config.EvictionPolicy)): case slices.Contains([]string{constants.AllKeysRandom}, strings.ToLower(server.config.EvictionPolicy)):
// Remove random keys until we're below the max memory limit // Remove random keys until we're below the max memory limit
// or there are no more keys remaining. // or there are no more keys remaining.
for { for {
@@ -449,7 +449,7 @@ func (server *EchoVault) adjustMemoryUsage(ctx context.Context) error {
idx-- idx--
} }
} }
case slices.Contains([]string{utils.VolatileRandom}, strings.ToLower(server.config.EvictionPolicy)): case slices.Contains([]string{constants.VolatileRandom}, strings.ToLower(server.config.EvictionPolicy)):
// Remove random keys with an associated expiry time until we're below the max memory limit // Remove random keys with an associated expiry time until we're below the max memory limit
// or there are no more keys with expiry time. // or there are no more keys with expiry time.
for { for {

View File

@@ -19,12 +19,13 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"net" "net"
"strings" "strings"
) )
func (server *EchoVault) GetAllCommands() []utils.Command { func (server *EchoVault) GetAllCommands() []types.Command {
return server.commands return server.commands
} }
@@ -36,13 +37,13 @@ func (server *EchoVault) GetPubSub() interface{} {
return server.PubSub return server.PubSub
} }
func (server *EchoVault) getCommand(cmd string) (utils.Command, error) { func (server *EchoVault) getCommand(cmd string) (types.Command, error) {
for _, command := range server.commands { for _, command := range server.commands {
if strings.EqualFold(command.Command, cmd) { if strings.EqualFold(command.Command, cmd) {
return command, nil return command, nil
} }
} }
return utils.Command{}, fmt.Errorf("command %s not supported", cmd) return types.Command{}, fmt.Errorf("command %s not supported", cmd)
} }
func (server *EchoVault) handleCommand(ctx context.Context, message []byte, conn *net.Conn, replay bool) ([]byte, error) { func (server *EchoVault) handleCommand(ctx context.Context, message []byte, conn *net.Conn, replay bool) ([]byte, error) {
@@ -59,7 +60,7 @@ func (server *EchoVault) handleCommand(ctx context.Context, message []byte, conn
synchronize := command.Sync synchronize := command.Sync
handler := command.HandlerFunc handler := command.HandlerFunc
subCommand, ok := internal.GetSubCommand(command, cmd).(utils.SubCommand) subCommand, ok := internal.GetSubCommand(command, cmd).(types.SubCommand)
if ok { if ok {
synchronize = subCommand.Sync synchronize = subCommand.Sync
handler = subCommand.HandlerFunc handler = subCommand.HandlerFunc
@@ -110,7 +111,7 @@ func (server *EchoVault) handleCommand(ctx context.Context, message []byte, conn
// Forward message to leader and return immediate OK response // Forward message to leader and return immediate OK response
if server.config.ForwardCommand { if server.config.ForwardCommand {
server.memberList.ForwardDataMutation(ctx, message) server.memberList.ForwardDataMutation(ctx, message)
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
return nil, errors.New("not cluster leader, cannot carry out command") return nil, errors.New("not cluster leader, cannot carry out command")

View File

@@ -20,7 +20,8 @@ import (
"errors" "errors"
"fmt" "fmt"
internal_acl "github.com/echovault/echovault/internal/acl" internal_acl "github.com/echovault/echovault/internal/acl"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"log" "log"
"net" "net"
@@ -30,9 +31,9 @@ import (
"strings" "strings"
) )
func handleAuth(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleAuth(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
if len(cmd) < 2 || len(cmd) > 3 { if len(cmd) < 2 || len(cmd) > 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
if !ok { if !ok {
@@ -41,12 +42,12 @@ func handleAuth(ctx context.Context, cmd []string, server utils.EchoVault, conn
if err := acl.AuthenticateConnection(ctx, conn, cmd); err != nil { if err := acl.AuthenticateConnection(ctx, conn, cmd); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleGetUser(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleGetUser(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
if len(cmd) != 3 { if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
@@ -161,9 +162,9 @@ func handleGetUser(_ context.Context, cmd []string, server utils.EchoVault, _ *n
return []byte(res), nil return []byte(res), nil
} }
func handleCat(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleCat(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
if len(cmd) > 3 { if len(cmd) > 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
categories := make(map[string][]string) categories := make(map[string][]string)
@@ -221,7 +222,7 @@ func handleCat(_ context.Context, cmd []string, server utils.EchoVault, _ *net.C
return nil, fmt.Errorf("category %s not found", strings.ToUpper(cmd[2])) return nil, fmt.Errorf("category %s not found", strings.ToUpper(cmd[2]))
} }
func handleUsers(_ context.Context, _ []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleUsers(_ context.Context, _ []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
if !ok { if !ok {
return nil, errors.New("could not load ACL") return nil, errors.New("could not load ACL")
@@ -234,7 +235,7 @@ func handleUsers(_ context.Context, _ []string, server utils.EchoVault, _ *net.C
return []byte(res), nil return []byte(res), nil
} }
func handleSetUser(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleSetUser(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
if !ok { if !ok {
return nil, errors.New("could not load ACL") return nil, errors.New("could not load ACL")
@@ -242,12 +243,12 @@ func handleSetUser(_ context.Context, cmd []string, server utils.EchoVault, _ *n
if err := acl.SetUser(cmd[2:]); err != nil { if err := acl.SetUser(cmd[2:]); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleDelUser(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleDelUser(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
if !ok { if !ok {
@@ -256,10 +257,10 @@ func handleDelUser(ctx context.Context, cmd []string, server utils.EchoVault, _
if err := acl.DeleteUser(ctx, cmd[2:]); err != nil { if err := acl.DeleteUser(ctx, cmd[2:]); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleWhoAmI(_ context.Context, _ []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleWhoAmI(_ context.Context, _ []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
if !ok { if !ok {
return nil, errors.New("could not load ACL") return nil, errors.New("could not load ACL")
@@ -268,9 +269,9 @@ func handleWhoAmI(_ context.Context, _ []string, server utils.EchoVault, conn *n
return []byte(fmt.Sprintf("+%s\r\n", connectionInfo.User.Username)), nil return []byte(fmt.Sprintf("+%s\r\n", connectionInfo.User.Username)), nil
} }
func handleList(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleList(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
if len(cmd) > 2 { if len(cmd) > 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
if !ok { if !ok {
@@ -364,9 +365,9 @@ func handleList(_ context.Context, cmd []string, server utils.EchoVault, _ *net.
return []byte(res), nil return []byte(res), nil
} }
func handleLoad(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleLoad(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
if len(cmd) != 3 { if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
@@ -428,12 +429,12 @@ func handleLoad(_ context.Context, cmd []string, server utils.EchoVault, _ *net.
} }
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleSave(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleSave(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
if len(cmd) > 2 { if len(cmd) > 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
acl, ok := server.GetACL().(*internal_acl.ACL) acl, ok := server.GetACL().(*internal_acl.ACL)
@@ -486,15 +487,15 @@ func handleSave(_ context.Context, cmd []string, server utils.EchoVault, _ *net.
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "auth", Command: "auth",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.ConnectionCategory, utils.SlowCategory}, Categories: []string{constants.ConnectionCategory, constants.SlowCategory},
Description: "(AUTH [username] password) Authenticates the connection", Description: "(AUTH [username] password) Authenticates the connection",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -504,18 +505,18 @@ func Commands() []utils.Command {
}, },
{ {
Command: "acl", Command: "acl",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{}, Categories: []string{},
Description: "Access-Control-List commands", Description: "Access-Control-List commands",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil return []string{}, nil
}, },
SubCommands: []utils.SubCommand{ SubCommands: []types.SubCommand{
{ {
Command: "cat", Command: "cat",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.SlowCategory}, Categories: []string{constants.SlowCategory},
Description: `(ACL CAT [category]) List all the categories. Description: `(ACL CAT [category]) List all the categories.
If the optional category is provided, list all the commands in the category`, If the optional category is provided, list all the commands in the category`,
Sync: false, Sync: false,
@@ -526,8 +527,8 @@ If the optional category is provided, list all the commands in the category`,
}, },
{ {
Command: "users", Command: "users",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL USERS) List all usernames of the configured ACL users", Description: "(ACL USERS) List all usernames of the configured ACL users",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -537,8 +538,8 @@ If the optional category is provided, list all the commands in the category`,
}, },
{ {
Command: "setuser", Command: "setuser",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL SETUSER) Configure a new or existing user", Description: "(ACL SETUSER) Configure a new or existing user",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -548,8 +549,8 @@ If the optional category is provided, list all the commands in the category`,
}, },
{ {
Command: "getuser", Command: "getuser",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL GETUSER username) List the ACL rules of a user", Description: "(ACL GETUSER username) List the ACL rules of a user",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -559,8 +560,8 @@ If the optional category is provided, list all the commands in the category`,
}, },
{ {
Command: "deluser", Command: "deluser",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL DELUSER username [username ...]) Deletes users and terminates their connections. Cannot delete default user", Description: "(ACL DELUSER username [username ...]) Deletes users and terminates their connections. Cannot delete default user",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -570,8 +571,8 @@ If the optional category is provided, list all the commands in the category`,
}, },
{ {
Command: "whoami", Command: "whoami",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.FastCategory}, Categories: []string{constants.FastCategory},
Description: "(ACL WHOAMI) Returns the authenticated user of the current connection", Description: "(ACL WHOAMI) Returns the authenticated user of the current connection",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -581,8 +582,8 @@ If the optional category is provided, list all the commands in the category`,
}, },
{ {
Command: "list", Command: "list",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL LIST) Dumps effective acl rules in acl config file format", Description: "(ACL LIST) Dumps effective acl rules in acl config file format",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -592,8 +593,8 @@ If the optional category is provided, list all the commands in the category`,
}, },
{ {
Command: "load", Command: "load",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: ` Description: `
(ACL LOAD <MERGE | REPLACE>) Reloads the rules from the configured ACL config file. (ACL LOAD <MERGE | REPLACE>) Reloads the rules from the configured ACL config file.
When 'MERGE' is passed, users from config file who share a username with users in memory will be merged. When 'MERGE' is passed, users from config file who share a username with users in memory will be merged.
@@ -606,8 +607,8 @@ When 'REPLACE' is passed, users from config file who share a username with users
}, },
{ {
Command: "save", Command: "save",
Module: utils.ACLModule, Module: constants.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL SAVE) Saves the effective ACL rules the configured ACL config file", Description: "(ACL SAVE) Saves the effective ACL rules the configured ACL config file",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {

View File

@@ -19,8 +19,8 @@ import (
"fmt" "fmt"
internal_acl "github.com/echovault/echovault/internal/acl" internal_acl "github.com/echovault/echovault/internal/acl"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"net" "net"
"slices" "slices"
@@ -48,7 +48,7 @@ func setUpServer(bindAddr string, port uint16, requirePass bool, aclConfig strin
BindAddr: bindAddr, BindAddr: bindAddr,
Port: port, Port: port,
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
RequirePass: requirePass, RequirePass: requirePass,
Password: "password1", Password: "password1",
AclConfig: aclConfig, AclConfig: aclConfig,
@@ -248,7 +248,7 @@ func Test_HandleAuth(t *testing.T) {
{ // 7. Command too short { // 7. Command too short
cmd: []resp.Value{resp.StringValue("AUTH")}, cmd: []resp.Value{resp.StringValue("AUTH")},
wantRes: "", wantRes: "",
wantErr: fmt.Sprintf("Error %s", utils.WrongArgsResponse), wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse),
}, },
{ // 8. Command too long { // 8. Command too long
cmd: []resp.Value{ cmd: []resp.Value{
@@ -258,7 +258,7 @@ func Test_HandleAuth(t *testing.T) {
resp.StringValue("password2"), resp.StringValue("password2"),
}, },
wantRes: "", wantRes: "",
wantErr: fmt.Sprintf("Error %s", utils.WrongArgsResponse), wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse),
}, },
} }
@@ -314,36 +314,36 @@ func Test_HandleCat(t *testing.T) {
{ // 1. Return list of categories { // 1. Return list of categories
cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT")}, cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT")},
wantRes: []string{ wantRes: []string{
utils.ConnectionCategory, constants.ConnectionCategory,
utils.SlowCategory, constants.SlowCategory,
utils.FastCategory, constants.FastCategory,
utils.AdminCategory, constants.AdminCategory,
utils.DangerousCategory, constants.DangerousCategory,
}, },
wantErr: "", wantErr: "",
}, },
{ // 2. Return list of commands in connection category { // 2. Return list of commands in connection category
cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(utils.ConnectionCategory)}, cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.ConnectionCategory)},
wantRes: []string{"auth"}, wantRes: []string{"auth"},
wantErr: "", wantErr: "",
}, },
{ // 3. Return list of commands in slow category { // 3. Return list of commands in slow category
cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(utils.SlowCategory)}, cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.SlowCategory)},
wantRes: []string{"auth", "acl|cat", "acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, wantRes: []string{"auth", "acl|cat", "acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"},
wantErr: "", wantErr: "",
}, },
{ // 4. Return list of commands in fast category { // 4. Return list of commands in fast category
cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(utils.FastCategory)}, cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.FastCategory)},
wantRes: []string{"acl|whoami"}, wantRes: []string{"acl|whoami"},
wantErr: "", wantErr: "",
}, },
{ // 5. Return list of commands in admin category { // 5. Return list of commands in admin category
cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(utils.AdminCategory)}, cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.AdminCategory)},
wantRes: []string{"acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, wantRes: []string{"acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"},
wantErr: "", wantErr: "",
}, },
{ // 6. Return list of commands in dangerous category { // 6. Return list of commands in dangerous category
cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(utils.DangerousCategory)}, cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.DangerousCategory)},
wantRes: []string{"acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, wantRes: []string{"acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"},
wantErr: "", wantErr: "",
}, },
@@ -355,7 +355,7 @@ func Test_HandleCat(t *testing.T) {
{ // 8. Command too long { // 8. Command too long
cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue("category1"), resp.StringValue("category2")}, cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue("category1"), resp.StringValue("category2")},
wantRes: nil, wantRes: nil,
wantErr: fmt.Sprintf("Error %s", utils.WrongArgsResponse), wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse),
}, },
} }
@@ -640,20 +640,20 @@ func Test_HandleSetUser(t *testing.T) {
resp.StringValue("SETUSER"), resp.StringValue("SETUSER"),
resp.StringValue("set_user_8"), resp.StringValue("set_user_8"),
resp.StringValue("on"), resp.StringValue("on"),
resp.StringValue(fmt.Sprintf("+@%s", utils.WriteCategory)), resp.StringValue(fmt.Sprintf("+@%s", constants.WriteCategory)),
resp.StringValue(fmt.Sprintf("+@%s", utils.ReadCategory)), resp.StringValue(fmt.Sprintf("+@%s", constants.ReadCategory)),
resp.StringValue(fmt.Sprintf("+@%s", utils.PubSubCategory)), resp.StringValue(fmt.Sprintf("+@%s", constants.PubSubCategory)),
resp.StringValue(fmt.Sprintf("-@%s", utils.AdminCategory)), resp.StringValue(fmt.Sprintf("-@%s", constants.AdminCategory)),
resp.StringValue(fmt.Sprintf("-@%s", utils.ConnectionCategory)), resp.StringValue(fmt.Sprintf("-@%s", constants.ConnectionCategory)),
resp.StringValue(fmt.Sprintf("-@%s", utils.DangerousCategory)), resp.StringValue(fmt.Sprintf("-@%s", constants.DangerousCategory)),
}, },
wantRes: "OK", wantRes: "OK",
wantErr: "", wantErr: "",
wantUser: func() *internal_acl.User { wantUser: func() *internal_acl.User {
user := internal_acl.CreateUser("set_user_8") user := internal_acl.CreateUser("set_user_8")
user.Enabled = true user.Enabled = true
user.IncludedCategories = []string{utils.WriteCategory, utils.ReadCategory, utils.PubSubCategory} user.IncludedCategories = []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}
user.ExcludedCategories = []string{utils.AdminCategory, utils.ConnectionCategory, utils.DangerousCategory} user.ExcludedCategories = []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}
user.Normalise() user.Normalise()
return user return user
}(), }(),
@@ -1065,8 +1065,8 @@ func Test_HandleGetUser(t *testing.T) {
{PasswordType: internal_acl.PasswordPlainText, PasswordValue: "get_user_password_1"}, {PasswordType: internal_acl.PasswordPlainText, PasswordValue: "get_user_password_1"},
{PasswordType: internal_acl.PasswordSHA256, PasswordValue: generateSHA256Password("get_user_password_2")}, {PasswordType: internal_acl.PasswordSHA256, PasswordValue: generateSHA256Password("get_user_password_2")},
}, },
IncludedCategories: []string{utils.WriteCategory, utils.ReadCategory, utils.PubSubCategory}, IncludedCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory},
ExcludedCategories: []string{utils.AdminCategory, utils.ConnectionCategory, utils.DangerousCategory}, ExcludedCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory},
IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"},
ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"},
IncludedReadKeys: []string{"key1", "key2", "key3", "key4"}, IncludedReadKeys: []string{"key1", "key2", "key3", "key4"},
@@ -1084,12 +1084,12 @@ func Test_HandleGetUser(t *testing.T) {
}), }),
resp.StringValue("categories"), resp.StringValue("categories"),
resp.ArrayValue([]resp.Value{ resp.ArrayValue([]resp.Value{
resp.StringValue(fmt.Sprintf("+@%s", utils.WriteCategory)), resp.StringValue(fmt.Sprintf("+@%s", constants.WriteCategory)),
resp.StringValue(fmt.Sprintf("+@%s", utils.ReadCategory)), resp.StringValue(fmt.Sprintf("+@%s", constants.ReadCategory)),
resp.StringValue(fmt.Sprintf("+@%s", utils.PubSubCategory)), resp.StringValue(fmt.Sprintf("+@%s", constants.PubSubCategory)),
resp.StringValue(fmt.Sprintf("-@%s", utils.AdminCategory)), resp.StringValue(fmt.Sprintf("-@%s", constants.AdminCategory)),
resp.StringValue(fmt.Sprintf("-@%s", utils.ConnectionCategory)), resp.StringValue(fmt.Sprintf("-@%s", constants.ConnectionCategory)),
resp.StringValue(fmt.Sprintf("-@%s", utils.DangerousCategory)), resp.StringValue(fmt.Sprintf("-@%s", constants.DangerousCategory)),
}), }),
resp.StringValue("commands"), resp.StringValue("commands"),
resp.ArrayValue([]resp.Value{ resp.ArrayValue([]resp.Value{
@@ -1219,7 +1219,7 @@ func Test_HandleDelUser(t *testing.T) {
presetUser: nil, presetUser: nil,
cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("DELUSER")}, cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("DELUSER")},
wantRes: "", wantRes: "",
wantErr: fmt.Sprintf("Error %s", utils.WrongArgsResponse), wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse),
}, },
} }
@@ -1353,8 +1353,8 @@ func Test_HandleList(t *testing.T) {
{PasswordType: internal_acl.PasswordPlainText, PasswordValue: "list_user_password_1"}, {PasswordType: internal_acl.PasswordPlainText, PasswordValue: "list_user_password_1"},
{PasswordType: internal_acl.PasswordSHA256, PasswordValue: generateSHA256Password("list_user_password_2")}, {PasswordType: internal_acl.PasswordSHA256, PasswordValue: generateSHA256Password("list_user_password_2")},
}, },
IncludedCategories: []string{utils.WriteCategory, utils.ReadCategory, utils.PubSubCategory}, IncludedCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory},
ExcludedCategories: []string{utils.AdminCategory, utils.ConnectionCategory, utils.DangerousCategory}, ExcludedCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory},
IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"},
ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"},
IncludedReadKeys: []string{"key1", "key2", "key3", "key4"}, IncludedReadKeys: []string{"key1", "key2", "key3", "key4"},
@@ -1368,8 +1368,8 @@ func Test_HandleList(t *testing.T) {
NoPassword: true, NoPassword: true,
NoKeys: true, NoKeys: true,
Passwords: []internal_acl.Password{}, Passwords: []internal_acl.Password{},
IncludedCategories: []string{utils.WriteCategory, utils.ReadCategory, utils.PubSubCategory}, IncludedCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory},
ExcludedCategories: []string{utils.AdminCategory, utils.ConnectionCategory, utils.DangerousCategory}, ExcludedCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory},
IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"},
ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"},
IncludedReadKeys: []string{}, IncludedReadKeys: []string{},
@@ -1386,8 +1386,8 @@ func Test_HandleList(t *testing.T) {
{PasswordType: internal_acl.PasswordPlainText, PasswordValue: "list_user_password_3"}, {PasswordType: internal_acl.PasswordPlainText, PasswordValue: "list_user_password_3"},
{PasswordType: internal_acl.PasswordSHA256, PasswordValue: generateSHA256Password("list_user_password_4")}, {PasswordType: internal_acl.PasswordSHA256, PasswordValue: generateSHA256Password("list_user_password_4")},
}, },
IncludedCategories: []string{utils.WriteCategory, utils.ReadCategory, utils.PubSubCategory}, IncludedCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory},
ExcludedCategories: []string{utils.AdminCategory, utils.ConnectionCategory, utils.DangerousCategory}, ExcludedCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory},
IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"},
ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"},
IncludedReadKeys: []string{"key1", "key2", "key3", "key4"}, IncludedReadKeys: []string{"key1", "key2", "key3", "key4"},

View File

@@ -18,14 +18,15 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"github.com/gobwas/glob" "github.com/gobwas/glob"
"net" "net"
"slices" "slices"
"strings" "strings"
) )
func handleGetAllCommands(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleGetAllCommands(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
commands := server.GetAllCommands() commands := server.GetAllCommands()
res := "" res := ""
@@ -70,7 +71,7 @@ func handleGetAllCommands(ctx context.Context, cmd []string, server utils.EchoVa
return []byte(res), nil return []byte(res), nil
} }
func handleCommandCount(_ context.Context, _ []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleCommandCount(_ context.Context, _ []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
var count int var count int
commands := server.GetAllCommands() commands := server.GetAllCommands()
@@ -87,7 +88,7 @@ func handleCommandCount(_ context.Context, _ []string, server utils.EchoVault, _
return []byte(fmt.Sprintf(":%d\r\n", count)), nil return []byte(fmt.Sprintf(":%d\r\n", count)), nil
} }
func handleCommandList(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleCommandList(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
switch len(cmd) { switch len(cmd) {
case 2: case 2:
// Command is COMMAND LIST // Command is COMMAND LIST
@@ -182,20 +183,20 @@ func handleCommandList(_ context.Context, cmd []string, server utils.EchoVault,
res = fmt.Sprintf("*%d\r\n%s", count, res) res = fmt.Sprintf("*%d\r\n%s", count, res)
return []byte(res), nil return []byte(res), nil
default: default:
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
} }
func handleCommandDocs(_ context.Context, _ []string, _ utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleCommandDocs(_ context.Context, _ []string, _ types.EchoVault, _ *net.Conn) ([]byte, error) {
return []byte("*0\r\n"), nil return []byte("*0\r\n"), nil
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "commands", Command: "commands",
Module: utils.AdminModule, Module: constants.AdminModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory},
Description: "Get a list of all the commands in available on the echovault with categories and descriptions", Description: "Get a list of all the commands in available on the echovault with categories and descriptions",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil }, KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
@@ -203,18 +204,18 @@ func Commands() []utils.Command {
}, },
{ {
Command: "command", Command: "command",
Module: utils.AdminModule, Module: constants.AdminModule,
Categories: []string{}, Categories: []string{},
Description: "Commands pertaining to echovault commands", Description: "Commands pertaining to echovault commands",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil return []string{}, nil
}, },
SubCommands: []utils.SubCommand{ SubCommands: []types.SubCommand{
{ {
Command: "docs", Command: "docs",
Module: utils.AdminModule, Module: constants.AdminModule,
Categories: []string{utils.SlowCategory, utils.ConnectionCategory}, Categories: []string{constants.SlowCategory, constants.ConnectionCategory},
Description: "Get command documentation", Description: "Get command documentation",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil }, KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
@@ -222,8 +223,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "count", Command: "count",
Module: utils.AdminModule, Module: constants.AdminModule,
Categories: []string{utils.SlowCategory}, Categories: []string{constants.SlowCategory},
Description: "Get the dumber of commands in the echovault", Description: "Get the dumber of commands in the echovault",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil }, KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
@@ -231,8 +232,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "list", Command: "list",
Module: utils.AdminModule, Module: constants.AdminModule,
Categories: []string{utils.SlowCategory}, Categories: []string{constants.SlowCategory},
Description: `(COMMAND LIST [FILTERBY <ACLCAT category | PATTERN pattern | MODULE module>]) Get the list of command names. Description: `(COMMAND LIST [FILTERBY <ACLCAT category | PATTERN pattern | MODULE module>]) Get the list of command names.
Allows for filtering by ACL category or glob pattern.`, Allows for filtering by ACL category or glob pattern.`,
Sync: false, Sync: false,
@@ -243,30 +244,30 @@ Allows for filtering by ACL category or glob pattern.`,
}, },
{ {
Command: "save", Command: "save",
Module: utils.AdminModule, Module: constants.AdminModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(SAVE) Trigger a snapshot save", Description: "(SAVE) Trigger a snapshot save",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil return []string{}, nil
}, },
HandlerFunc: func(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { HandlerFunc: func(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
if err := server.TakeSnapshot(); err != nil { if err := server.TakeSnapshot(); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
}, },
}, },
{ {
Command: "lastsave", Command: "lastsave",
Module: utils.AdminModule, Module: constants.AdminModule,
Categories: []string{utils.AdminCategory, utils.FastCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.FastCategory, constants.DangerousCategory},
Description: "(LASTSAVE) Get unix timestamp for the latest snapshot in milliseconds.", Description: "(LASTSAVE) Get unix timestamp for the latest snapshot in milliseconds.",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil return []string{}, nil
}, },
HandlerFunc: func(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { HandlerFunc: func(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
msec := server.GetLatestSnapshot() msec := server.GetLatestSnapshot()
if msec == 0 { if msec == 0 {
return nil, errors.New("no snapshot") return nil, errors.New("no snapshot")
@@ -276,18 +277,18 @@ Allows for filtering by ACL category or glob pattern.`,
}, },
{ {
Command: "rewriteaof", Command: "rewriteaof",
Module: utils.AdminModule, Module: constants.AdminModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(REWRITEAOF) Trigger re-writing of append process", Description: "(REWRITEAOF) Trigger re-writing of append process",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil return []string{}, nil
}, },
HandlerFunc: func(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { HandlerFunc: func(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
if err := server.RewriteAOF(); err != nil { if err := server.RewriteAOF(); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
}, },
}, },
} }

View File

@@ -19,8 +19,8 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"testing" "testing"
) )
@@ -29,7 +29,7 @@ func Test_CommandsHandler(t *testing.T) {
mockServer := echovault.NewEchoVault( mockServer := echovault.NewEchoVault(
echovault.WithConfig(config.Config{ echovault.WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
echovault.WithCommands(Commands()), echovault.WithCommands(Commands()),
) )

View File

@@ -18,14 +18,15 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"net" "net"
) )
func handlePing(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handlePing(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
switch len(cmd) { switch len(cmd) {
default: default:
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
case 1: case 1:
return []byte("+PONG\r\n"), nil return []byte("+PONG\r\n"), nil
case 2: case 2:
@@ -33,12 +34,12 @@ func handlePing(ctx context.Context, cmd []string, server utils.EchoVault, conn
} }
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "connection", Command: "connection",
Module: utils.ConnectionModule, Module: constants.ConnectionModule,
Categories: []string{utils.FastCategory, utils.ConnectionCategory}, Categories: []string{constants.FastCategory, constants.ConnectionCategory},
Description: "(PING [value]) Ping the echovault. If a value is provided, the value will be echoed.", Description: "(PING [value]) Ping the echovault. If a value is provided, the value will be echoed.",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {

View File

@@ -19,8 +19,8 @@ import (
"context" "context"
"errors" "errors"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"testing" "testing"
) )
@@ -31,7 +31,7 @@ func init() {
mockServer = echovault.NewEchoVault( mockServer = echovault.NewEchoVault(
echovault.WithConfig(config.Config{ echovault.WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
} }
@@ -57,7 +57,7 @@ func Test_HandlePing(t *testing.T) {
{ {
command: []string{"PING", "Hello, world!", "Once more"}, command: []string{"PING", "Hello, world!", "Once more"},
expected: "", expected: "",
expectedErr: errors.New(utils.WrongArgsResponse), expectedErr: errors.New(constants.WrongArgsResponse),
}, },
} }

View File

@@ -20,7 +20,8 @@ import (
"flag" "flag"
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"log" "log"
"net" "net"
"strconv" "strconv"
@@ -48,7 +49,7 @@ type KeyObject struct {
locked bool locked bool
} }
func handleSet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleSet(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := setKeyFunc(cmd) keys, err := setKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -56,7 +57,7 @@ func handleSet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
key := keys[0] key := keys[0]
value := cmd[2] value := cmd[2]
res := []byte(utils.OkResponse) res := []byte(constants.OkResponse)
params, err := getSetCommandParams(cmd[3:], SetParams{}) params, err := getSetCommandParams(cmd[3:], SetParams{})
if err != nil { if err != nil {
@@ -112,7 +113,7 @@ func handleSet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
return res, nil return res, nil
} }
func handleMSet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleMSet(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
if _, err := msetKeyFunc(cmd); err != nil { if _, err := msetKeyFunc(cmd); err != nil {
return nil, err return nil, err
} }
@@ -165,10 +166,10 @@ func handleMSet(ctx context.Context, cmd []string, server utils.EchoVault, _ *ne
} }
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleGet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleGet(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := getKeyFunc(cmd) keys, err := getKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -190,7 +191,7 @@ func handleGet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
return []byte(fmt.Sprintf("+%v\r\n", value)), nil return []byte(fmt.Sprintf("+%v\r\n", value)), nil
} }
func handleMGet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleMGet(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := mgetKeyFunc(cmd) keys, err := mgetKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -240,7 +241,7 @@ func handleMGet(ctx context.Context, cmd []string, server utils.EchoVault, _ *ne
return bytes, nil return bytes, nil
} }
func handleDel(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleDel(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := delKeyFunc(cmd) keys, err := delKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -257,7 +258,7 @@ func handleDel(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
return []byte(fmt.Sprintf(":%d\r\n", count)), nil return []byte(fmt.Sprintf(":%d\r\n", count)), nil
} }
func handlePersist(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handlePersist(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := persistKeyFunc(cmd) keys, err := persistKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -284,7 +285,7 @@ func handlePersist(ctx context.Context, cmd []string, server utils.EchoVault, _
return []byte(":1\r\n"), nil return []byte(":1\r\n"), nil
} }
func handleExpireTime(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleExpireTime(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := expireTimeKeyFunc(cmd) keys, err := expireTimeKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -315,7 +316,7 @@ func handleExpireTime(ctx context.Context, cmd []string, server utils.EchoVault,
return []byte(fmt.Sprintf(":%d\r\n", t)), nil return []byte(fmt.Sprintf(":%d\r\n", t)), nil
} }
func handleTTL(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleTTL(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := ttlKeyFunc(cmd) keys, err := ttlKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -350,7 +351,7 @@ func handleTTL(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
return []byte(fmt.Sprintf(":%d\r\n", t)), nil return []byte(fmt.Sprintf(":%d\r\n", t)), nil
} }
func handleExpire(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleExpire(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := expireKeyFunc(cmd) keys, err := expireKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -418,7 +419,7 @@ func handleExpire(ctx context.Context, cmd []string, server utils.EchoVault, _ *
return []byte(":1\r\n"), nil return []byte(":1\r\n"), nil
} }
func handleExpireAt(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleExpireAt(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := expireKeyFunc(cmd) keys, err := expireKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -486,12 +487,12 @@ func handleExpireAt(ctx context.Context, cmd []string, server utils.EchoVault, _
return []byte(":1\r\n"), nil return []byte(":1\r\n"), nil
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "set", Command: "set",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.WriteCategory, constants.SlowCategory},
Description: ` Description: `
(SET key value [NX | XX] [GET] [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds]) (SET key value [NX | XX] [GET] [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds])
Set the value of a key, considering the value's type. Set the value of a key, considering the value's type.
@@ -508,8 +509,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
}, },
{ {
Command: "mset", Command: "mset",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.WriteCategory, constants.SlowCategory},
Description: "(MSET key value [key value ...]) Automatically generic or modify multiple key/value pairs.", Description: "(MSET key value [key value ...]) Automatically generic or modify multiple key/value pairs.",
Sync: true, Sync: true,
KeyExtractionFunc: msetKeyFunc, KeyExtractionFunc: msetKeyFunc,
@@ -517,8 +518,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
}, },
{ {
Command: "get", Command: "get",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.ReadCategory, constants.FastCategory},
Description: "(GET key) Get the value at the specified key.", Description: "(GET key) Get the value at the specified key.",
Sync: false, Sync: false,
KeyExtractionFunc: getKeyFunc, KeyExtractionFunc: getKeyFunc,
@@ -526,8 +527,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
}, },
{ {
Command: "mget", Command: "mget",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.ReadCategory, constants.FastCategory},
Description: "(MGET key [key ...]) Get multiple values from the specified keys.", Description: "(MGET key [key ...]) Get multiple values from the specified keys.",
Sync: false, Sync: false,
KeyExtractionFunc: mgetKeyFunc, KeyExtractionFunc: mgetKeyFunc,
@@ -535,8 +536,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
}, },
{ {
Command: "del", Command: "del",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: "(DEL key [key ...]) Removes one or more keys from the store.", Description: "(DEL key [key ...]) Removes one or more keys from the store.",
Sync: true, Sync: true,
KeyExtractionFunc: delKeyFunc, KeyExtractionFunc: delKeyFunc,
@@ -544,8 +545,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
}, },
{ {
Command: "persist", Command: "persist",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: `(PERSIST key) Removes the TTl associated with a key, Description: `(PERSIST key) Removes the TTl associated with a key,
turning it from a volatile key to a persistent key.`, turning it from a volatile key to a persistent key.`,
Sync: true, Sync: true,
@@ -554,8 +555,8 @@ turning it from a volatile key to a persistent key.`,
}, },
{ {
Command: "expiretime", Command: "expiretime",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.ReadCategory, constants.FastCategory},
Description: `(EXPIRETIME key) Returns the absolute unix time in seconds when the key will expire. Description: `(EXPIRETIME key) Returns the absolute unix time in seconds when the key will expire.
Return -1 if the key exists but has no associated expiry time. Return -1 if the key exists but has no associated expiry time.
Returns -2 if the key does not exist.`, Returns -2 if the key does not exist.`,
@@ -565,8 +566,8 @@ Returns -2 if the key does not exist.`,
}, },
{ {
Command: "pexpiretime", Command: "pexpiretime",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.ReadCategory, constants.FastCategory},
Description: `(PEXPIRETIME key) Returns the absolute unix time in milliseconds when the key will expire. Description: `(PEXPIRETIME key) Returns the absolute unix time in milliseconds when the key will expire.
Return -1 if the key exists but has no associated expiry time. Return -1 if the key exists but has no associated expiry time.
Returns -2 if the key does not exist.`, Returns -2 if the key does not exist.`,
@@ -576,8 +577,8 @@ Returns -2 if the key does not exist.`,
}, },
{ {
Command: "ttl", Command: "ttl",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.ReadCategory, constants.FastCategory},
Description: `(TTL key) Returns the remaining time to live for a key that has an expiry time in seconds. Description: `(TTL key) Returns the remaining time to live for a key that has an expiry time in seconds.
If the key exists but does not have an associated expiry time, -1 is returned. If the key exists but does not have an associated expiry time, -1 is returned.
If the key does not exist, -2 is returned.`, If the key does not exist, -2 is returned.`,
@@ -587,8 +588,8 @@ If the key does not exist, -2 is returned.`,
}, },
{ {
Command: "pttl", Command: "pttl",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.ReadCategory, constants.FastCategory},
Description: `(PTTL key) Returns the remaining time to live for a key that has an expiry time in milliseconds. Description: `(PTTL key) Returns the remaining time to live for a key that has an expiry time in milliseconds.
If the key exists but does not have an associated expiry time, -1 is returned. If the key exists but does not have an associated expiry time, -1 is returned.
If the key does not exist, -2 is returned.`, If the key does not exist, -2 is returned.`,
@@ -598,8 +599,8 @@ If the key does not exist, -2 is returned.`,
}, },
{ {
Command: "expire", Command: "expire",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: `(EXPIRE key seconds [NX | XX | GT | LT]) Description: `(EXPIRE key seconds [NX | XX | GT | LT])
Expire the key in the specified number of seconds. This commands turns a key into a volatile one. Expire the key in the specified number of seconds. This commands turns a key into a volatile one.
NX - Only set the expiry time if the key has no associated expiry. NX - Only set the expiry time if the key has no associated expiry.
@@ -612,8 +613,8 @@ LT - Only set the expiry time if the new expiry time is less than the current on
}, },
{ {
Command: "pexpire", Command: "pexpire",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: `(PEXPIRE key milliseconds [NX | XX | GT | LT]) Description: `(PEXPIRE key milliseconds [NX | XX | GT | LT])
Expire the key in the specified number of milliseconds. This commands turns a key into a volatile one. Expire the key in the specified number of milliseconds. This commands turns a key into a volatile one.
NX - Only set the expiry time if the key has no associated expiry. NX - Only set the expiry time if the key has no associated expiry.
@@ -626,8 +627,8 @@ LT - Only set the expiry time if the new expiry time is less than the current on
}, },
{ {
Command: "expireat", Command: "expireat",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: `(EXPIREAT key unix-time-seconds [NX | XX | GT | LT]) Description: `(EXPIREAT key unix-time-seconds [NX | XX | GT | LT])
Expire the key in at the exact unix time in seconds. Expire the key in at the exact unix time in seconds.
This commands turns a key into a volatile one. This commands turns a key into a volatile one.
@@ -641,8 +642,8 @@ LT - Only set the expiry time if the new expiry time is less than the current on
}, },
{ {
Command: "pexpireat", Command: "pexpireat",
Module: utils.GenericModule, Module: constants.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: `(PEXPIREAT key unix-time-milliseconds [NX | XX | GT | LT]) Description: `(PEXPIREAT key unix-time-milliseconds [NX | XX | GT | LT])
Expire the key in at the exact unix time in milliseconds. Expire the key in at the exact unix time in milliseconds.
This commands turns a key into a volatile one. This commands turns a key into a volatile one.

View File

@@ -20,8 +20,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"testing" "testing"
"time" "time"
@@ -38,7 +38,7 @@ func init() {
mockServer = echovault.NewEchoVault( mockServer = echovault.NewEchoVault(
echovault.WithConfig(config.Config{ echovault.WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
} }
@@ -309,13 +309,13 @@ func Test_HandleSET(t *testing.T) {
command: []string{"SET"}, command: []string{"SET"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: nil, expectedValue: nil,
expectedErr: errors.New(utils.WrongArgsResponse), expectedErr: errors.New(constants.WrongArgsResponse),
}, },
{ // 30. Command too long { // 30. Command too long
command: []string{"SET", "SetKey30", "value1", "value2", "value3", "value4", "value5", "value6"}, command: []string{"SET", "SetKey30", "value1", "value2", "value3", "value4", "value5", "value6"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: nil, expectedValue: nil,
expectedErr: errors.New(utils.WrongArgsResponse), expectedErr: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -524,11 +524,11 @@ func Test_HandleGET(t *testing.T) {
}{ }{
{ {
command: []string{"GET"}, command: []string{"GET"},
expected: utils.WrongArgsResponse, expected: constants.WrongArgsResponse,
}, },
{ {
command: []string{"GET", "GetKey1", "test"}, command: []string{"GET", "GetKey1", "test"},
expected: utils.WrongArgsResponse, expected: constants.WrongArgsResponse,
}, },
} }
for _, test := range errorTests { for _, test := range errorTests {
@@ -569,7 +569,7 @@ func Test_HandleMGET(t *testing.T) {
presetValues: []string{"value5"}, presetValues: []string{"value5"},
command: []string{"MGET"}, command: []string{"MGET"},
expected: nil, expected: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -650,7 +650,7 @@ func Test_HandleDEL(t *testing.T) {
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectToExist: nil, expectToExist: nil,
expectedErr: errors.New(utils.WrongArgsResponse), expectedErr: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -745,14 +745,14 @@ func Test_HandlePERSIST(t *testing.T) {
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedValues: nil, expectedValues: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Command too long { // 5. Command too long
command: []string{"PERSIST", "PersistKey5", "key6"}, command: []string{"PERSIST", "PersistKey5", "key6"},
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedValues: nil, expectedValues: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -858,13 +858,13 @@ func Test_HandleEXPIRETIME(t *testing.T) {
command: []string{"PEXPIRETIME"}, command: []string{"PEXPIRETIME"},
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 6. Command too long { // 6. Command too long
command: []string{"PEXPIRETIME", "ExpireTimeKey5", "ExpireTimeKey6"}, command: []string{"PEXPIRETIME", "ExpireTimeKey5", "ExpireTimeKey6"},
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -951,13 +951,13 @@ func Test_HandleTTL(t *testing.T) {
command: []string{"TTL"}, command: []string{"TTL"},
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 6. Command too long { // 6. Command too long
command: []string{"TTL", "TTLKey5", "TTLKey6"}, command: []string{"TTL", "TTLKey5", "TTLKey6"},
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1164,14 +1164,14 @@ func Test_HandleEXPIRE(t *testing.T) {
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedValues: nil, expectedValues: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 16. Command too long { // 16. Command too long
command: []string{"EXPIRE", "ExpireKey16", "10", "NX", "GT"}, command: []string{"EXPIRE", "ExpireKey16", "10", "NX", "GT"},
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedValues: nil, expectedValues: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1421,14 +1421,14 @@ func Test_HandleEXPIREAT(t *testing.T) {
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedValues: nil, expectedValues: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 16. Command too long { // 16. Command too long
command: []string{"EXPIREAT", "ExpireAtKey16", "10", "NX", "GT"}, command: []string{"EXPIREAT", "ExpireAtKey16", "10", "NX", "GT"},
presetValues: nil, presetValues: nil,
expectedResponse: 0, expectedResponse: 0,
expectedValues: nil, expectedValues: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }

View File

@@ -16,12 +16,12 @@ package generic
import ( import (
"errors" "errors"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
) )
func setKeyFunc(cmd []string) ([]string, error) { func setKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 || len(cmd) > 7 { if len(cmd) < 3 || len(cmd) > 7 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
@@ -41,56 +41,56 @@ func msetKeyFunc(cmd []string) ([]string, error) {
func getKeyFunc(cmd []string) ([]string, error) { func getKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func mgetKeyFunc(cmd []string) ([]string, error) { func mgetKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func delKeyFunc(cmd []string) ([]string, error) { func delKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func persistKeyFunc(cmd []string) ([]string, error) { func persistKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func expireTimeKeyFunc(cmd []string) ([]string, error) { func expireTimeKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func ttlKeyFunc(cmd []string) ([]string, error) { func ttlKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func expireKeyFunc(cmd []string) ([]string, error) { func expireKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 || len(cmd) > 4 { if len(cmd) < 3 || len(cmd) > 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func expireAtKeyFunc(cmd []string) ([]string, error) { func expireAtKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 || len(cmd) > 4 { if len(cmd) < 3 || len(cmd) > 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }

View File

@@ -19,7 +19,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"math/rand" "math/rand"
"net" "net"
"slices" "slices"
@@ -27,7 +28,7 @@ import (
"strings" "strings"
) )
func handleHSET(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleHSET(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := hsetKeyFunc(cmd) keys, err := hsetKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -85,7 +86,7 @@ func handleHSET(ctx context.Context, cmd []string, server utils.EchoVault, _ *ne
return []byte(fmt.Sprintf(":%d\r\n", count)), nil return []byte(fmt.Sprintf(":%d\r\n", count)), nil
} }
func handleHGET(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleHGET(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := hgetKeyFunc(cmd) keys, err := hgetKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -136,7 +137,7 @@ func handleHGET(ctx context.Context, cmd []string, server utils.EchoVault, _ *ne
return []byte(res), nil return []byte(res), nil
} }
func handleHSTRLEN(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHSTRLEN(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hstrlenKeyFunc(cmd) keys, err := hstrlenKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -187,7 +188,7 @@ func handleHSTRLEN(ctx context.Context, cmd []string, server utils.EchoVault, co
return []byte(res), nil return []byte(res), nil
} }
func handleHVALS(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHVALS(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hvalsKeyFunc(cmd) keys, err := hvalsKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -228,7 +229,7 @@ func handleHVALS(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(res), nil return []byte(res), nil
} }
func handleHRANDFIELD(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHRANDFIELD(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hrandfieldKeyFunc(cmd) keys, err := hrandfieldKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -344,7 +345,7 @@ func handleHRANDFIELD(ctx context.Context, cmd []string, server utils.EchoVault,
return []byte(res), nil return []byte(res), nil
} }
func handleHLEN(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHLEN(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hlenKeyFunc(cmd) keys, err := hlenKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -369,7 +370,7 @@ func handleHLEN(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", len(hash))), nil return []byte(fmt.Sprintf(":%d\r\n", len(hash))), nil
} }
func handleHKEYS(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHKEYS(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hkeysKeyFunc(cmd) keys, err := hkeysKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -399,7 +400,7 @@ func handleHKEYS(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(res), nil return []byte(res), nil
} }
func handleHINCRBY(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHINCRBY(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hincrbyKeyFunc(cmd) keys, err := hincrbyKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -491,7 +492,7 @@ func handleHINCRBY(ctx context.Context, cmd []string, server utils.EchoVault, co
return []byte(fmt.Sprintf(":%d\r\n", i)), nil return []byte(fmt.Sprintf(":%d\r\n", i)), nil
} }
func handleHGETALL(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHGETALL(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hgetallKeyFunc(cmd) keys, err := hgetallKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -531,7 +532,7 @@ func handleHGETALL(ctx context.Context, cmd []string, server utils.EchoVault, co
return []byte(res), nil return []byte(res), nil
} }
func handleHEXISTS(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHEXISTS(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hexistsKeyFunc(cmd) keys, err := hexistsKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -561,7 +562,7 @@ func handleHEXISTS(ctx context.Context, cmd []string, server utils.EchoVault, co
return []byte(":0\r\n"), nil return []byte(":0\r\n"), nil
} }
func handleHDEL(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleHDEL(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := hdelKeyFunc(cmd) keys, err := hdelKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -600,12 +601,12 @@ func handleHDEL(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", count)), nil return []byte(fmt.Sprintf(":%d\r\n", count)), nil
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "hset", Command: "hset",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.WriteCategory, constants.FastCategory},
Description: `(HSET key field value [field value ...]) Set update each field of the hash with the corresponding value`, Description: `(HSET key field value [field value ...]) Set update each field of the hash with the corresponding value`,
Sync: true, Sync: true,
KeyExtractionFunc: hsetKeyFunc, KeyExtractionFunc: hsetKeyFunc,
@@ -613,8 +614,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "hsetnx", Command: "hsetnx",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.WriteCategory, constants.FastCategory},
Description: `(HSETNX key field value [field value ...]) Set hash field value only if the field does not exist`, Description: `(HSETNX key field value [field value ...]) Set hash field value only if the field does not exist`,
Sync: true, Sync: true,
KeyExtractionFunc: hsetnxKeyFunc, KeyExtractionFunc: hsetnxKeyFunc,
@@ -622,8 +623,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "hget", Command: "hget",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HGET key field [field ...]) Retrieve the value of each of the listed fields from the hash`, Description: `(HGET key field [field ...]) Retrieve the value of each of the listed fields from the hash`,
Sync: false, Sync: false,
KeyExtractionFunc: hgetKeyFunc, KeyExtractionFunc: hgetKeyFunc,
@@ -631,8 +632,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "hstrlen", Command: "hstrlen",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HSTRLEN key field [field ...]) Description: `(HSTRLEN key field [field ...])
Return the string length of the values stored at the specified fields. 0 if the value does not exist`, Return the string length of the values stored at the specified fields. 0 if the value does not exist`,
Sync: false, Sync: false,
@@ -641,8 +642,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hvals", Command: "hvals",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(HVALS key) Returns all the values of the hash at key.`, Description: `(HVALS key) Returns all the values of the hash at key.`,
Sync: false, Sync: false,
KeyExtractionFunc: hvalsKeyFunc, KeyExtractionFunc: hvalsKeyFunc,
@@ -650,8 +651,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hrandfield", Command: "hrandfield",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(HRANDFIELD key [count [WITHVALUES]]) Returns one or more random fields from the hash`, Description: `(HRANDFIELD key [count [WITHVALUES]]) Returns one or more random fields from the hash`,
Sync: false, Sync: false,
KeyExtractionFunc: hrandfieldKeyFunc, KeyExtractionFunc: hrandfieldKeyFunc,
@@ -659,8 +660,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hlen", Command: "hlen",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HLEN key) Returns the number of fields in the hash`, Description: `(HLEN key) Returns the number of fields in the hash`,
Sync: false, Sync: false,
KeyExtractionFunc: hlenKeyFunc, KeyExtractionFunc: hlenKeyFunc,
@@ -668,8 +669,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hkeys", Command: "hkeys",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(HKEYS key) Returns all the fields in a hash`, Description: `(HKEYS key) Returns all the fields in a hash`,
Sync: false, Sync: false,
KeyExtractionFunc: hkeysKeyFunc, KeyExtractionFunc: hkeysKeyFunc,
@@ -677,8 +678,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hincrbyfloat", Command: "hincrbyfloat",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.WriteCategory, constants.FastCategory},
Description: `(HINCRBYFLOAT key field increment) Increment the hash value by the float increment`, Description: `(HINCRBYFLOAT key field increment) Increment the hash value by the float increment`,
Sync: true, Sync: true,
KeyExtractionFunc: hincrbyKeyFunc, KeyExtractionFunc: hincrbyKeyFunc,
@@ -686,8 +687,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hincrby", Command: "hincrby",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.WriteCategory, constants.FastCategory},
Description: `(HINCRBY key field increment) Increment the hash value by the integer increment`, Description: `(HINCRBY key field increment) Increment the hash value by the integer increment`,
Sync: true, Sync: true,
KeyExtractionFunc: hincrbyKeyFunc, KeyExtractionFunc: hincrbyKeyFunc,
@@ -695,8 +696,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hgetall", Command: "hgetall",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(HGETALL key) Get all fields and values of a hash`, Description: `(HGETALL key) Get all fields and values of a hash`,
Sync: false, Sync: false,
KeyExtractionFunc: hgetallKeyFunc, KeyExtractionFunc: hgetallKeyFunc,
@@ -704,8 +705,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hexists", Command: "hexists",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HEXISTS key field) Returns if field is an existing field in the hash`, Description: `(HEXISTS key field) Returns if field is an existing field in the hash`,
Sync: false, Sync: false,
KeyExtractionFunc: hexistsKeyFunc, KeyExtractionFunc: hexistsKeyFunc,
@@ -713,8 +714,8 @@ Return the string length of the values stored at the specified fields. 0 if the
}, },
{ {
Command: "hdel", Command: "hdel",
Module: utils.HashModule, Module: constants.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HDEL key field [field ...]) Deletes the specified fields from the hash`, Description: `(HDEL key field [field ...]) Deletes the specified fields from the hash`,
Sync: true, Sync: true,
KeyExtractionFunc: hdelKeyFunc, KeyExtractionFunc: hdelKeyFunc,

View File

@@ -20,8 +20,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"slices" "slices"
"testing" "testing"
@@ -33,7 +33,7 @@ func init() {
mockServer = echovault.NewEchoVault( mockServer = echovault.NewEchoVault(
echovault.WithConfig(config.Config{ echovault.WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
} }
@@ -119,7 +119,7 @@ func Test_HandleHSET(t *testing.T) {
command: []string{"HSET", "field1"}, command: []string{"HSET", "field1"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -219,7 +219,7 @@ func Test_HandleHINCRBY(t *testing.T) {
command: []string{"HINCRBY", "HincrbyKey5"}, command: []string{"HINCRBY", "HincrbyKey5"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -228,7 +228,7 @@ func Test_HandleHINCRBY(t *testing.T) {
command: []string{"HINCRBY", "HincrbyKey6", "field1", "23", "45"}, command: []string{"HINCRBY", "HincrbyKey6", "field1", "23", "45"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Error when increment by float does not pass valid float { // Error when increment by float does not pass valid float
preset: false, preset: false,
@@ -364,7 +364,7 @@ func Test_HandleHGET(t *testing.T) {
command: []string{"HGET", "HgetKey4"}, command: []string{"HGET", "HgetKey4"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -457,7 +457,7 @@ func Test_HandleHSTRLEN(t *testing.T) {
command: []string{"HSTRLEN", "HstrlenKey3"}, command: []string{"HSTRLEN", "HstrlenKey3"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get lengths on a non hash map returns error { // Trying to get lengths on a non hash map returns error
preset: true, preset: true,
@@ -545,7 +545,7 @@ func Test_HandleHVALS(t *testing.T) {
command: []string{"HVALS"}, command: []string{"HVALS"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -554,7 +554,7 @@ func Test_HandleHVALS(t *testing.T) {
command: []string{"HVALS", "HvalsKey4", "HvalsKey4"}, command: []string{"HVALS", "HvalsKey4", "HvalsKey4"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get lengths on a non hash map returns error { // Trying to get lengths on a non hash map returns error
preset: true, preset: true,
@@ -729,14 +729,14 @@ func Test_HandleHRANDFIELD(t *testing.T) {
key: "HrandfieldKey10", key: "HrandfieldKey10",
presetValue: map[string]interface{}{}, presetValue: map[string]interface{}{},
command: []string{"HRANDFIELD"}, command: []string{"HRANDFIELD"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
key: "HrandfieldKey11", key: "HrandfieldKey11",
presetValue: map[string]interface{}{}, presetValue: map[string]interface{}{},
command: []string{"HRANDFIELD", "HrandfieldKey11", "HrandfieldKey11", "HrandfieldKey11", "HrandfieldKey11"}, command: []string{"HRANDFIELD", "HrandfieldKey11", "HrandfieldKey11", "HrandfieldKey11", "HrandfieldKey11"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get random field on a non hash map returns error { // Trying to get random field on a non hash map returns error
preset: true, preset: true,
@@ -855,7 +855,7 @@ func Test_HandleHLEN(t *testing.T) {
command: []string{"HLEN"}, command: []string{"HLEN"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -864,7 +864,7 @@ func Test_HandleHLEN(t *testing.T) {
command: []string{"HLEN", "HlenKey4", "HlenKey4"}, command: []string{"HLEN", "HlenKey4", "HlenKey4"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get lengths on a non hash map returns error { // Trying to get lengths on a non hash map returns error
preset: true, preset: true,
@@ -947,7 +947,7 @@ func Test_HandleHKeys(t *testing.T) {
command: []string{"HKEYS"}, command: []string{"HKEYS"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -956,7 +956,7 @@ func Test_HandleHKeys(t *testing.T) {
command: []string{"HKEYS", "HkeysKey4", "HkeysKey4"}, command: []string{"HKEYS", "HkeysKey4", "HkeysKey4"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get lengths on a non hash map returns error { // Trying to get lengths on a non hash map returns error
preset: true, preset: true,
@@ -1046,7 +1046,7 @@ func Test_HandleHGETALL(t *testing.T) {
command: []string{"HGETALL"}, command: []string{"HGETALL"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -1055,7 +1055,7 @@ func Test_HandleHGETALL(t *testing.T) {
command: []string{"HGETALL", "HGetAllKey4", "HGetAllKey4"}, command: []string{"HGETALL", "HGetAllKey4", "HGetAllKey4"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get lengths on a non hash map returns error { // Trying to get lengths on a non hash map returns error
preset: true, preset: true,
@@ -1156,7 +1156,7 @@ func Test_HandleHEXISTS(t *testing.T) {
command: []string{"HEXISTS", "HexistsKey3"}, command: []string{"HEXISTS", "HexistsKey3"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -1165,7 +1165,7 @@ func Test_HandleHEXISTS(t *testing.T) {
command: []string{"HEXISTS", "HexistsKey4", "field1", "field2"}, command: []string{"HEXISTS", "HexistsKey4", "field1", "field2"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get lengths on a non hash map returns error { // Trying to get lengths on a non hash map returns error
preset: true, preset: true,
@@ -1257,7 +1257,7 @@ func Test_HandleHDEL(t *testing.T) {
command: []string{"HDEL", "HdelKey4"}, command: []string{"HDEL", "HdelKey4"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get lengths on a non hash map returns error { // Trying to get lengths on a non hash map returns error
preset: true, preset: true,

View File

@@ -16,47 +16,47 @@ package hash
import ( import (
"errors" "errors"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
) )
func hsetKeyFunc(cmd []string) ([]string, error) { func hsetKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 4 { if len(cmd) < 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func hsetnxKeyFunc(cmd []string) ([]string, error) { func hsetnxKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 4 { if len(cmd) < 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func hgetKeyFunc(cmd []string) ([]string, error) { func hgetKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func hstrlenKeyFunc(cmd []string) ([]string, error) { func hstrlenKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func hvalsKeyFunc(cmd []string) ([]string, error) { func hvalsKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func hrandfieldKeyFunc(cmd []string) ([]string, error) { func hrandfieldKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 || len(cmd) > 4 { if len(cmd) < 2 || len(cmd) > 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
if len(cmd) == 2 { if len(cmd) == 2 {
return cmd[1:], nil return cmd[1:], nil
@@ -66,42 +66,42 @@ func hrandfieldKeyFunc(cmd []string) ([]string, error) {
func hlenKeyFunc(cmd []string) ([]string, error) { func hlenKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func hkeysKeyFunc(cmd []string) ([]string, error) { func hkeysKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func hincrbyKeyFunc(cmd []string) ([]string, error) { func hincrbyKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func hgetallKeyFunc(cmd []string) ([]string, error) { func hgetallKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func hexistsKeyFunc(cmd []string) ([]string, error) { func hexistsKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 3 { if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func hdelKeyFunc(cmd []string) ([]string, error) { func hdelKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }

View File

@@ -19,14 +19,15 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"math" "math"
"net" "net"
"slices" "slices"
"strings" "strings"
) )
func handleLLen(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleLLen(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := llenKeyFunc(cmd) keys, err := llenKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -51,7 +52,7 @@ func handleLLen(ctx context.Context, cmd []string, server utils.EchoVault, _ *ne
return nil, errors.New("LLEN command on non-list item") return nil, errors.New("LLEN command on non-list item")
} }
func handleLIndex(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleLIndex(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := lindexKeyFunc(cmd) keys, err := lindexKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -85,7 +86,7 @@ func handleLIndex(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(fmt.Sprintf("+%s\r\n", list[index])), nil return []byte(fmt.Sprintf("+%s\r\n", list[index])), nil
} }
func handleLRange(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleLRange(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := lrangeKeyFunc(cmd) keys, err := lrangeKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -164,7 +165,7 @@ func handleLRange(ctx context.Context, cmd []string, server utils.EchoVault, con
return bytes, nil return bytes, nil
} }
func handleLSet(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleLSet(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := lsetKeyFunc(cmd) keys, err := lsetKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -200,10 +201,10 @@ func handleLSet(ctx context.Context, cmd []string, server utils.EchoVault, conn
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleLTrim(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleLTrim(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := ltrimKeyFunc(cmd) keys, err := ltrimKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -243,16 +244,16 @@ func handleLTrim(ctx context.Context, cmd []string, server utils.EchoVault, conn
if err = server.SetValue(ctx, key, list[start:]); err != nil { if err = server.SetValue(ctx, key, list[start:]); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
if err = server.SetValue(ctx, key, list[start:end]); err != nil { if err = server.SetValue(ctx, key, list[start:end]); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleLRem(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleLRem(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := lremKeyFunc(cmd) keys, err := lremKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -317,10 +318,10 @@ func handleLRem(ctx context.Context, cmd []string, server utils.EchoVault, conn
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleLMove(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleLMove(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := lmoveKeyFunc(cmd) keys, err := lmoveKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -378,10 +379,10 @@ func handleLMove(ctx context.Context, cmd []string, server utils.EchoVault, conn
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleLPush(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleLPush(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := lpushKeyFunc(cmd) keys, err := lpushKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -424,10 +425,10 @@ func handleLPush(ctx context.Context, cmd []string, server utils.EchoVault, conn
if err = server.SetValue(ctx, key, append(newElems, l...)); err != nil { if err = server.SetValue(ctx, key, append(newElems, l...)); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handleRPush(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleRPush(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := rpushKeyFunc(cmd) keys, err := rpushKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -472,10 +473,10 @@ func handleRPush(ctx context.Context, cmd []string, server utils.EchoVault, conn
if err = server.SetValue(ctx, key, append(l, newElems...)); err != nil { if err = server.SetValue(ctx, key, append(l, newElems...)); err != nil {
return nil, err return nil, err
} }
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handlePop(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handlePop(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := popKeyFunc(cmd) keys, err := popKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -511,12 +512,12 @@ func handlePop(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
} }
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "lpush", Command: "lpush",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(LPUSH key element [element ...]) Prepends one or more values to the beginning of a list, creates the list if it does not exist.", Description: "(LPUSH key element [element ...]) Prepends one or more values to the beginning of a list, creates the list if it does not exist.",
Sync: true, Sync: true,
KeyExtractionFunc: lpushKeyFunc, KeyExtractionFunc: lpushKeyFunc,
@@ -524,8 +525,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "lpushx", Command: "lpushx",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(LPUSHX key element [element ...]) Prepends a value to the beginning of a list only if the list exists.", Description: "(LPUSHX key element [element ...]) Prepends a value to the beginning of a list only if the list exists.",
Sync: true, Sync: true,
KeyExtractionFunc: lpushKeyFunc, KeyExtractionFunc: lpushKeyFunc,
@@ -533,8 +534,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "lpop", Command: "lpop",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(LPOP key) Removes and returns the first element of a list.", Description: "(LPOP key) Removes and returns the first element of a list.",
Sync: true, Sync: true,
KeyExtractionFunc: popKeyFunc, KeyExtractionFunc: popKeyFunc,
@@ -542,8 +543,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "llen", Command: "llen",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.ListCategory, constants.ReadCategory, constants.FastCategory},
Description: "(LLEN key) Return the length of a list.", Description: "(LLEN key) Return the length of a list.",
Sync: false, Sync: false,
KeyExtractionFunc: llenKeyFunc, KeyExtractionFunc: llenKeyFunc,
@@ -551,8 +552,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "lrange", Command: "lrange",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.ListCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(LRANGE key start end) Return a range of elements between the given indices.", Description: "(LRANGE key start end) Return a range of elements between the given indices.",
Sync: false, Sync: false,
KeyExtractionFunc: lrangeKeyFunc, KeyExtractionFunc: lrangeKeyFunc,
@@ -560,8 +561,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "lindex", Command: "lindex",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.ListCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(LINDEX key index) Gets list element by index.", Description: "(LINDEX key index) Gets list element by index.",
Sync: false, Sync: false,
KeyExtractionFunc: lindexKeyFunc, KeyExtractionFunc: lindexKeyFunc,
@@ -569,8 +570,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "lset", Command: "lset",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(LSET key index element) Sets the value of an element in a list by its index.", Description: "(LSET key index element) Sets the value of an element in a list by its index.",
Sync: true, Sync: true,
KeyExtractionFunc: lsetKeyFunc, KeyExtractionFunc: lsetKeyFunc,
@@ -578,8 +579,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "ltrim", Command: "ltrim",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(LTRIM key start end) Trims a list to the specified range.", Description: "(LTRIM key start end) Trims a list to the specified range.",
Sync: true, Sync: true,
KeyExtractionFunc: ltrimKeyFunc, KeyExtractionFunc: ltrimKeyFunc,
@@ -587,8 +588,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "lrem", Command: "lrem",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(LREM key count element) Remove elements from list.", Description: "(LREM key count element) Remove elements from list.",
Sync: true, Sync: true,
KeyExtractionFunc: lremKeyFunc, KeyExtractionFunc: lremKeyFunc,
@@ -596,8 +597,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "lmove", Command: "lmove",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(LMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT>) Move element from one list to the other specifying left/right for both lists.", Description: "(LMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT>) Move element from one list to the other specifying left/right for both lists.",
Sync: true, Sync: true,
KeyExtractionFunc: lmoveKeyFunc, KeyExtractionFunc: lmoveKeyFunc,
@@ -605,8 +606,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "rpop", Command: "rpop",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(RPOP key) Removes and gets the last element in a list.", Description: "(RPOP key) Removes and gets the last element in a list.",
Sync: true, Sync: true,
KeyExtractionFunc: popKeyFunc, KeyExtractionFunc: popKeyFunc,
@@ -614,8 +615,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "rpush", Command: "rpush",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(RPUSH key element [element ...]) Appends one or multiple elements to the end of a list.", Description: "(RPUSH key element [element ...]) Appends one or multiple elements to the end of a list.",
Sync: true, Sync: true,
KeyExtractionFunc: rpushKeyFunc, KeyExtractionFunc: rpushKeyFunc,
@@ -623,8 +624,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "rpushx", Command: "rpushx",
Module: utils.ListModule, Module: constants.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(RPUSHX key element [element ...]) Appends an element to the end of a list, only if the list exists.", Description: "(RPUSHX key element [element ...]) Appends an element to the end of a list, only if the list exists.",
Sync: true, Sync: true,
KeyExtractionFunc: rpushKeyFunc, KeyExtractionFunc: rpushKeyFunc,

View File

@@ -20,8 +20,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"testing" "testing"
) )
@@ -32,7 +32,7 @@ func init() {
mockServer = echovault.NewEchoVault( mockServer = echovault.NewEchoVault(
echovault.WithConfig(config.Config{ echovault.WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
} }
@@ -72,7 +72,7 @@ func Test_HandleLLEN(t *testing.T) {
command: []string{"LLEN"}, command: []string{"LLEN"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -81,7 +81,7 @@ func Test_HandleLLEN(t *testing.T) {
command: []string{"LLEN", "LlenKey4", "LlenKey4"}, command: []string{"LLEN", "LlenKey4", "LlenKey4"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get lengths on a non-list returns error { // Trying to get lengths on a non-list returns error
preset: true, preset: true,
@@ -177,7 +177,7 @@ func Test_HandleLINDEX(t *testing.T) {
command: []string{"LINDEX", "LindexKey3"}, command: []string{"LINDEX", "LindexKey3"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -186,7 +186,7 @@ func Test_HandleLINDEX(t *testing.T) {
command: []string{"LINDEX", "LindexKey4", "0", "20"}, command: []string{"LINDEX", "LindexKey4", "0", "20"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get element by index on a non-list returns error { // Trying to get element by index on a non-list returns error
preset: true, preset: true,
@@ -312,7 +312,7 @@ func Test_HandleLRANGE(t *testing.T) {
command: []string{"LRANGE", "LrangeKey5"}, command: []string{"LRANGE", "LrangeKey5"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -321,7 +321,7 @@ func Test_HandleLRANGE(t *testing.T) {
command: []string{"LRANGE", "LrangeKey6", "0", "element", "element"}, command: []string{"LRANGE", "LrangeKey6", "0", "element", "element"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Error when executing command on non-list command { // Error when executing command on non-list command
preset: true, preset: true,
@@ -468,7 +468,7 @@ func Test_HandleLSET(t *testing.T) {
command: []string{"LSET", "LsetKey5"}, command: []string{"LSET", "LsetKey5"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -477,7 +477,7 @@ func Test_HandleLSET(t *testing.T) {
command: []string{"LSET", "LsetKey6", "0", "element", "element"}, command: []string{"LSET", "LsetKey6", "0", "element", "element"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get element by index on a non-list returns error { // Trying to get element by index on a non-list returns error
preset: true, preset: true,
@@ -619,7 +619,7 @@ func Test_HandleLTRIM(t *testing.T) {
command: []string{"LTRIM", "LtrimKey5"}, command: []string{"LTRIM", "LtrimKey5"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -628,7 +628,7 @@ func Test_HandleLTRIM(t *testing.T) {
command: []string{"LTRIM", "LtrimKey6", "0", "element", "element"}, command: []string{"LTRIM", "LtrimKey6", "0", "element", "element"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to get element by index on a non-list returns error { // Trying to get element by index on a non-list returns error
preset: true, preset: true,
@@ -758,7 +758,7 @@ func Test_HandleLREM(t *testing.T) {
command: []string{"LREM", "LremKey5"}, command: []string{"LREM", "LremKey5"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -767,7 +767,7 @@ func Test_HandleLREM(t *testing.T) {
command: []string{"LREM", "LremKey6", "0", "element", "element"}, command: []string{"LREM", "LremKey6", "0", "element", "element"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Throw error when count is not an integer { // Throw error when count is not an integer
preset: false, preset: false,
@@ -976,7 +976,7 @@ func Test_HandleLMOVE(t *testing.T) {
command: []string{"LMOVE", "source9", "destination9"}, command: []string{"LMOVE", "source9", "destination9"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ {
// 10. Throw error when command is too long // 10. Throw error when command is too long
@@ -985,7 +985,7 @@ func Test_HandleLMOVE(t *testing.T) {
command: []string{"LMOVE", "source10", "destination10", "LEFT", "LEFT", "RIGHT"}, command: []string{"LMOVE", "source10", "destination10", "LEFT", "LEFT", "RIGHT"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: map[string]interface{}{}, expectedValue: map[string]interface{}{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ {
// 11. Throw error when WHEREFROM argument is not LEFT/RIGHT // 11. Throw error when WHEREFROM argument is not LEFT/RIGHT
@@ -1105,7 +1105,7 @@ func Test_HandleLPUSH(t *testing.T) {
command: []string{"LPUSH", "LpushKey5"}, command: []string{"LPUSH", "LpushKey5"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // LPUSHX command returns error on non-existent list { // LPUSHX command returns error on non-existent list
preset: false, preset: false,
@@ -1208,7 +1208,7 @@ func Test_HandleRPUSH(t *testing.T) {
command: []string{"RPUSH", "RpushKey5"}, command: []string{"RPUSH", "RpushKey5"},
expectedResponse: nil, expectedResponse: nil,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // RPUSHX command returns error on non-existent list { // RPUSHX command returns error on non-existent list
preset: false, preset: false,
@@ -1302,7 +1302,7 @@ func Test_HandlePOP(t *testing.T) {
command: []string{"LPOP"}, command: []string{"LPOP"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
@@ -1311,7 +1311,7 @@ func Test_HandlePOP(t *testing.T) {
command: []string{"LPOP", "PopKey4", "PopKey4"}, command: []string{"LPOP", "PopKey4", "PopKey4"},
expectedResponse: 0, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Trying to execute LPOP from a non-list item return an error { // Trying to execute LPOP from a non-list item return an error
preset: true, preset: true,

View File

@@ -16,75 +16,75 @@ package list
import ( import (
"errors" "errors"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
) )
func lpushKeyFunc(cmd []string) ([]string, error) { func lpushKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func popKeyFunc(cmd []string) ([]string, error) { func popKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func llenKeyFunc(cmd []string) ([]string, error) { func llenKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func lrangeKeyFunc(cmd []string) ([]string, error) { func lrangeKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func lindexKeyFunc(cmd []string) ([]string, error) { func lindexKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 3 { if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func lsetKeyFunc(cmd []string) ([]string, error) { func lsetKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func ltrimKeyFunc(cmd []string) ([]string, error) { func ltrimKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func lremKeyFunc(cmd []string) ([]string, error) { func lremKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func rpushKeyFunc(cmd []string) ([]string, error) { func rpushKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func lmoveKeyFunc(cmd []string) ([]string, error) { func lmoveKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 5 { if len(cmd) != 5 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1], cmd[2]}, nil return []string{cmd[1], cmd[2]}, nil
} }

View File

@@ -19,12 +19,13 @@ import (
"errors" "errors"
"fmt" "fmt"
internal_pubsub "github.com/echovault/echovault/internal/pubsub" internal_pubsub "github.com/echovault/echovault/internal/pubsub"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"net" "net"
"strings" "strings"
) )
func handleSubscribe(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSubscribe(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub) pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub)
if !ok { if !ok {
return nil, errors.New("could not load pubsub module") return nil, errors.New("could not load pubsub module")
@@ -33,7 +34,7 @@ func handleSubscribe(ctx context.Context, cmd []string, server utils.EchoVault,
channels := cmd[1:] channels := cmd[1:]
if len(channels) == 0 { if len(channels) == 0 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
withPattern := strings.EqualFold(cmd[0], "psubscribe") withPattern := strings.EqualFold(cmd[0], "psubscribe")
@@ -42,7 +43,7 @@ func handleSubscribe(ctx context.Context, cmd []string, server utils.EchoVault,
return nil, nil return nil, nil
} }
func handleUnsubscribe(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleUnsubscribe(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub) pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub)
if !ok { if !ok {
return nil, errors.New("could not load pubsub module") return nil, errors.New("could not load pubsub module")
@@ -55,21 +56,21 @@ func handleUnsubscribe(ctx context.Context, cmd []string, server utils.EchoVault
return pubsub.Unsubscribe(ctx, conn, channels, withPattern), nil return pubsub.Unsubscribe(ctx, conn, channels, withPattern), nil
} }
func handlePublish(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handlePublish(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub) pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub)
if !ok { if !ok {
return nil, errors.New("could not load pubsub module") return nil, errors.New("could not load pubsub module")
} }
if len(cmd) != 3 { if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
pubsub.Publish(ctx, cmd[2], cmd[1]) pubsub.Publish(ctx, cmd[2], cmd[1])
return []byte(utils.OkResponse), nil return []byte(constants.OkResponse), nil
} }
func handlePubSubChannels(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handlePubSubChannels(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
if len(cmd) > 3 { if len(cmd) > 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub) pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub)
@@ -85,7 +86,7 @@ func handlePubSubChannels(_ context.Context, cmd []string, server utils.EchoVaul
return pubsub.Channels(pattern), nil return pubsub.Channels(pattern), nil
} }
func handlePubSubNumPat(_ context.Context, _ []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handlePubSubNumPat(_ context.Context, _ []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub) pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub)
if !ok { if !ok {
return nil, errors.New("could not load pubsub module") return nil, errors.New("could not load pubsub module")
@@ -94,7 +95,7 @@ func handlePubSubNumPat(_ context.Context, _ []string, server utils.EchoVault, _
return []byte(fmt.Sprintf(":%d\r\n", num)), nil return []byte(fmt.Sprintf(":%d\r\n", num)), nil
} }
func handlePubSubNumSubs(_ context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handlePubSubNumSubs(_ context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub) pubsub, ok := server.GetPubSub().(*internal_pubsub.PubSub)
if !ok { if !ok {
return nil, errors.New("could not load pubsub module") return nil, errors.New("could not load pubsub module")
@@ -102,18 +103,18 @@ func handlePubSubNumSubs(_ context.Context, cmd []string, server utils.EchoVault
return pubsub.NumSub(cmd[2:]), nil return pubsub.NumSub(cmd[2:]), nil
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "subscribe", Command: "subscribe",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.ConnectionCategory, utils.SlowCategory}, Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory},
Description: "(SUBSCRIBE channel [channel ...]) Subscribe to one or more channels.", Description: "(SUBSCRIBE channel [channel ...]) Subscribe to one or more channels.",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the channels as keys // Treat the channels as keys
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
}, },
@@ -121,14 +122,14 @@ func Commands() []utils.Command {
}, },
{ {
Command: "psubscribe", Command: "psubscribe",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.ConnectionCategory, utils.SlowCategory}, Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory},
Description: "(PSUBSCRIBE pattern [pattern ...]) Subscribe to one or more glob patterns.", Description: "(PSUBSCRIBE pattern [pattern ...]) Subscribe to one or more glob patterns.",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the patterns as keys // Treat the patterns as keys
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
}, },
@@ -136,14 +137,14 @@ func Commands() []utils.Command {
}, },
{ {
Command: "publish", Command: "publish",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.FastCategory}, Categories: []string{constants.PubSubCategory, constants.FastCategory},
Description: "(PUBLISH channel message) Publish a message to the specified channel.", Description: "(PUBLISH channel message) Publish a message to the specified channel.",
Sync: true, Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) { KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the channel as a key // Treat the channel as a key
if len(cmd) != 3 { if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
}, },
@@ -151,8 +152,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "unsubscribe", Command: "unsubscribe",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.ConnectionCategory, utils.SlowCategory}, Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory},
Description: `(UNSUBSCRIBE [channel [channel ...]]) Unsubscribe from a list of channels. Description: `(UNSUBSCRIBE [channel [channel ...]]) Unsubscribe from a list of channels.
If the channel list is not provided, then the connection will be unsubscribed from all the channels that If the channel list is not provided, then the connection will be unsubscribed from all the channels that
it's currently subscribe to.`, it's currently subscribe to.`,
@@ -165,8 +166,8 @@ it's currently subscribe to.`,
}, },
{ {
Command: "punsubscribe", Command: "punsubscribe",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.ConnectionCategory, utils.SlowCategory}, Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory},
Description: `(PUNSUBSCRIBE [pattern [pattern ...]]) Unsubscribe from a list of channels using patterns. Description: `(PUNSUBSCRIBE [pattern [pattern ...]]) Unsubscribe from a list of channels using patterns.
If the pattern list is not provided, then the connection will be unsubscribed from all the patterns that If the pattern list is not provided, then the connection will be unsubscribed from all the patterns that
it's currently subscribe to.`, it's currently subscribe to.`,
@@ -179,19 +180,19 @@ it's currently subscribe to.`,
}, },
{ {
Command: "pubsub", Command: "pubsub",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{}, Categories: []string{},
Description: "", Description: "",
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil }, KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
HandlerFunc: func(_ context.Context, _ []string, _ utils.EchoVault, _ *net.Conn) ([]byte, error) { HandlerFunc: func(_ context.Context, _ []string, _ types.EchoVault, _ *net.Conn) ([]byte, error) {
return nil, errors.New("provide CHANNELS, NUMPAT, or NUMSUB subcommand") return nil, errors.New("provide CHANNELS, NUMPAT, or NUMSUB subcommand")
}, },
SubCommands: []utils.SubCommand{ SubCommands: []types.SubCommand{
{ {
Command: "channels", Command: "channels",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.SlowCategory}, Categories: []string{constants.PubSubCategory, constants.SlowCategory},
Description: `(PUBSUB CHANNELS [pattern]) Returns an array containing the list of channels that Description: `(PUBSUB CHANNELS [pattern]) Returns an array containing the list of channels that
match the given pattern. If no pattern is provided, all active channels are returned. Active channels are match the given pattern. If no pattern is provided, all active channels are returned. Active channels are
channels with 1 or more subscribers.`, channels with 1 or more subscribers.`,
@@ -201,8 +202,8 @@ channels with 1 or more subscribers.`,
}, },
{ {
Command: "numpat", Command: "numpat",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.SlowCategory}, Categories: []string{constants.PubSubCategory, constants.SlowCategory},
Description: `(PUBSUB NUMPAT) Return the number of patterns that are currently subscribed to by clients.`, Description: `(PUBSUB NUMPAT) Return the number of patterns that are currently subscribed to by clients.`,
Sync: false, Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil }, KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
@@ -210,8 +211,8 @@ channels with 1 or more subscribers.`,
}, },
{ {
Command: "numsub", Command: "numsub",
Module: utils.PubSubModule, Module: constants.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.SlowCategory}, Categories: []string{constants.PubSubCategory, constants.SlowCategory},
Description: `(PUBSUB NUMSUB [channel [channel ...]]) Return an array of arrays containing the provided 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.`, channel name and how many clients are currently subscribed to the channel.`,
Sync: false, Sync: false,

View File

@@ -20,8 +20,8 @@ import (
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
internal_pubsub "github.com/echovault/echovault/internal/pubsub" internal_pubsub "github.com/echovault/echovault/internal/pubsub"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"net" "net"
"slices" "slices"
@@ -50,7 +50,7 @@ func setUpServer(bindAddr string, port uint16) *echovault.EchoVault {
BindAddr: bindAddr, BindAddr: bindAddr,
Port: port, Port: port,
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
} }

View File

@@ -20,13 +20,14 @@ import (
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
set2 "github.com/echovault/echovault/internal/set" set2 "github.com/echovault/echovault/internal/set"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"net" "net"
"slices" "slices"
"strings" "strings"
) )
func handleSADD(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSADD(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := saddKeyFunc(cmd) keys, err := saddKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -63,7 +64,7 @@ func handleSADD(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", count)), nil return []byte(fmt.Sprintf(":%d\r\n", count)), nil
} }
func handleSCARD(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSCARD(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := scardKeyFunc(cmd) keys, err := scardKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -90,7 +91,7 @@ func handleSCARD(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", cardinality)), nil return []byte(fmt.Sprintf(":%d\r\n", cardinality)), nil
} }
func handleSDIFF(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSDIFF(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sdiffKeyFunc(cmd) keys, err := sdiffKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -151,7 +152,7 @@ func handleSDIFF(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(res), nil return []byte(res), nil
} }
func handleSDIFFSTORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSDIFFSTORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sdiffstoreKeyFunc(cmd) keys, err := sdiffstoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -227,7 +228,7 @@ func handleSDIFFSTORE(ctx context.Context, cmd []string, server utils.EchoVault,
return []byte(res), nil return []byte(res), nil
} }
func handleSINTER(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSINTER(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sinterKeyFunc(cmd) keys, err := sinterKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -282,7 +283,7 @@ func handleSINTER(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(res), nil return []byte(res), nil
} }
func handleSINTERCARD(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSINTERCARD(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sintercardKeyFunc(cmd) keys, err := sintercardKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -294,7 +295,7 @@ func handleSINTERCARD(ctx context.Context, cmd []string, server utils.EchoVault,
return strings.EqualFold(s, "limit") return strings.EqualFold(s, "limit")
}) })
if limitIdx >= 0 && limitIdx < 2 { if limitIdx >= 0 && limitIdx < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
if limitIdx != -1 { if limitIdx != -1 {
limitIdx += 1 limitIdx += 1
@@ -349,7 +350,7 @@ func handleSINTERCARD(ctx context.Context, cmd []string, server utils.EchoVault,
return []byte(fmt.Sprintf(":%d\r\n", intersect.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", intersect.Cardinality())), nil
} }
func handleSINTERSTORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSINTERSTORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sinterstoreKeyFunc(cmd) keys, err := sinterstoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -407,7 +408,7 @@ func handleSINTERSTORE(ctx context.Context, cmd []string, server utils.EchoVault
return []byte(fmt.Sprintf(":%d\r\n", intersect.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", intersect.Cardinality())), nil
} }
func handleSISMEMBER(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSISMEMBER(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sismemberKeyFunc(cmd) keys, err := sismemberKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -436,7 +437,7 @@ func handleSISMEMBER(ctx context.Context, cmd []string, server utils.EchoVault,
return []byte(":1\r\n"), nil return []byte(":1\r\n"), nil
} }
func handleSMEMBERS(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSMEMBERS(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := smembersKeyFunc(cmd) keys, err := smembersKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -471,7 +472,7 @@ func handleSMEMBERS(ctx context.Context, cmd []string, server utils.EchoVault, c
return []byte(res), nil return []byte(res), nil
} }
func handleSMISMEMBER(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSMISMEMBER(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := smismemberKeyFunc(cmd) keys, err := smismemberKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -514,7 +515,7 @@ func handleSMISMEMBER(ctx context.Context, cmd []string, server utils.EchoVault,
return []byte(res), nil return []byte(res), nil
} }
func handleSMOVE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSMOVE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := smoveKeyFunc(cmd) keys, err := smoveKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -568,7 +569,7 @@ func handleSMOVE(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", res)), nil return []byte(fmt.Sprintf(":%d\r\n", res)), nil
} }
func handleSPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSPOP(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := spopKeyFunc(cmd) keys, err := spopKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -612,7 +613,7 @@ func handleSPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(res), nil return []byte(res), nil
} }
func handleSRANDMEMBER(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSRANDMEMBER(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := srandmemberKeyFunc(cmd) keys, err := srandmemberKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -656,7 +657,7 @@ func handleSRANDMEMBER(ctx context.Context, cmd []string, server utils.EchoVault
return []byte(res), nil return []byte(res), nil
} }
func handleSREM(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSREM(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sremKeyFunc(cmd) keys, err := sremKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -684,7 +685,7 @@ func handleSREM(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", count)), nil return []byte(fmt.Sprintf(":%d\r\n", count)), nil
} }
func handleSUNION(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSUNION(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sunionKeyFunc(cmd) keys, err := sunionKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -735,7 +736,7 @@ func handleSUNION(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(res), nil return []byte(res), nil
} }
func handleSUNIONSTORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSUNIONSTORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := sunionstoreKeyFunc(cmd) keys, err := sunionstoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -794,12 +795,12 @@ func handleSUNIONSTORE(ctx context.Context, cmd []string, server utils.EchoVault
return []byte(fmt.Sprintf(":%d\r\n", union.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", union.Cardinality())), nil
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "sadd", Command: "sadd",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.FastCategory},
Description: "(SADD key member [member...]) Add one or more members to the set. If the set does not exist, it's created.", Description: "(SADD key member [member...]) Add one or more members to the set. If the set does not exist, it's created.",
Sync: true, Sync: true,
KeyExtractionFunc: saddKeyFunc, KeyExtractionFunc: saddKeyFunc,
@@ -807,8 +808,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "scard", Command: "scard",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.FastCategory},
Description: "(SCARD key) Returns the cardinality of the set.", Description: "(SCARD key) Returns the cardinality of the set.",
Sync: false, Sync: false,
KeyExtractionFunc: scardKeyFunc, KeyExtractionFunc: scardKeyFunc,
@@ -816,8 +817,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "sdiff", Command: "sdiff",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(SDIFF key [key...]) Returns the difference between all the sets in the given keys. Description: `(SDIFF key [key...]) Returns the difference between all the sets in the given keys.
If the first key provided is the only valid set, then this key's set will be returned as the result. If the first key provided is the only valid set, then this key's set will be returned as the result.
All keys that are non-existed or hold values that are not sets will be skipped.`, All keys that are non-existed or hold values that are not sets will be skipped.`,
@@ -827,8 +828,8 @@ All keys that are non-existed or hold values that are not sets will be skipped.`
}, },
{ {
Command: "sdiffstore", Command: "sdiffstore",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(SDIFFSTORE destination key [key...]) Works the same as SDIFF but also stores the result at 'destination'. Description: `(SDIFFSTORE destination key [key...]) Works the same as SDIFF but also stores the result at 'destination'.
Returns the cardinality of the new set`, Returns the cardinality of the new set`,
Sync: true, Sync: true,
@@ -837,8 +838,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "sinter", Command: "sinter",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SINTER key [key...]) Returns the intersection of multiple sets.", Description: "(SINTER key [key...]) Returns the intersection of multiple sets.",
Sync: false, Sync: false,
KeyExtractionFunc: sinterKeyFunc, KeyExtractionFunc: sinterKeyFunc,
@@ -846,8 +847,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "sintercard", Command: "sintercard",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SINTERCARD key [key...] [LIMIT limit]) Returns the cardinality of the intersection between multiple sets.", Description: "(SINTERCARD key [key...] [LIMIT limit]) Returns the cardinality of the intersection between multiple sets.",
Sync: false, Sync: false,
KeyExtractionFunc: sintercardKeyFunc, KeyExtractionFunc: sintercardKeyFunc,
@@ -855,8 +856,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "sinterstore", Command: "sinterstore",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SINTERSTORE destination key [key...]) Stores the intersection of multiple sets at the destination key.", Description: "(SINTERSTORE destination key [key...]) Stores the intersection of multiple sets at the destination key.",
Sync: true, Sync: true,
KeyExtractionFunc: sinterstoreKeyFunc, KeyExtractionFunc: sinterstoreKeyFunc,
@@ -864,8 +865,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "sismember", Command: "sismember",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.SetCategory, constants.ReadCategory, constants.FastCategory},
Description: "(SISMEMBER key member) Returns if member is contained in the set.", Description: "(SISMEMBER key member) Returns if member is contained in the set.",
Sync: false, Sync: false,
KeyExtractionFunc: sismemberKeyFunc, KeyExtractionFunc: sismemberKeyFunc,
@@ -873,8 +874,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "smembers", Command: "smembers",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SMEMBERS key) Returns all members of a set.", Description: "(SMEMBERS key) Returns all members of a set.",
Sync: false, Sync: false,
KeyExtractionFunc: smembersKeyFunc, KeyExtractionFunc: smembersKeyFunc,
@@ -882,8 +883,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "smismember", Command: "smismember",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.SetCategory, constants.ReadCategory, constants.FastCategory},
Description: "(SMISMEMBER key member [member...]) Returns if multiple members are in the set.", Description: "(SMISMEMBER key member [member...]) Returns if multiple members are in the set.",
Sync: false, Sync: false,
KeyExtractionFunc: smismemberKeyFunc, KeyExtractionFunc: smismemberKeyFunc,
@@ -892,8 +893,8 @@ Returns the cardinality of the new set`,
{ {
Command: "smove", Command: "smove",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.FastCategory},
Description: "(SMOVE source destination member) Moves a member from source set to destination set.", Description: "(SMOVE source destination member) Moves a member from source set to destination set.",
Sync: true, Sync: true,
KeyExtractionFunc: smoveKeyFunc, KeyExtractionFunc: smoveKeyFunc,
@@ -901,8 +902,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "spop", Command: "spop",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SPOP key [count]) Returns and removes one or more random members from the set.", Description: "(SPOP key [count]) Returns and removes one or more random members from the set.",
Sync: true, Sync: true,
KeyExtractionFunc: spopKeyFunc, KeyExtractionFunc: spopKeyFunc,
@@ -910,8 +911,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "srandmember", Command: "srandmember",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SRANDMEMBER key [count]) Returns one or more random members from the set without removing them.", Description: "(SRANDMEMBER key [count]) Returns one or more random members from the set without removing them.",
Sync: false, Sync: false,
KeyExtractionFunc: srandmemberKeyFunc, KeyExtractionFunc: srandmemberKeyFunc,
@@ -919,8 +920,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "srem", Command: "srem",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.FastCategory},
Description: "(SREM key member [member...]) Remove one or more members from a set.", Description: "(SREM key member [member...]) Remove one or more members from a set.",
Sync: true, Sync: true,
KeyExtractionFunc: sremKeyFunc, KeyExtractionFunc: sremKeyFunc,
@@ -928,8 +929,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "sunion", Command: "sunion",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SUNION key [key...]) Returns the members of the set resulting from the union of the provided sets.", Description: "(SUNION key [key...]) Returns the members of the set resulting from the union of the provided sets.",
Sync: false, Sync: false,
KeyExtractionFunc: sunionKeyFunc, KeyExtractionFunc: sunionKeyFunc,
@@ -937,8 +938,8 @@ Returns the cardinality of the new set`,
}, },
{ {
Command: "sunionstore", Command: "sunionstore",
Module: utils.SetModule, Module: constants.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SUNIONSTORE destination key [key...]) Stores the union of the given sets into destination.", Description: "(SUNIONSTORE destination key [key...]) Stores the union of the given sets into destination.",
Sync: true, Sync: true,
KeyExtractionFunc: sunionstoreKeyFunc, KeyExtractionFunc: sunionstoreKeyFunc,

View File

@@ -21,8 +21,8 @@ import (
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/internal/set" "github.com/echovault/echovault/internal/set"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"slices" "slices"
"testing" "testing"
@@ -34,7 +34,7 @@ func init() {
mockServer = echovault.NewEchoVault( mockServer = echovault.NewEchoVault(
echovault.WithConfig(config.Config{ echovault.WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
} }
@@ -81,7 +81,7 @@ func Test_HandleSADD(t *testing.T) {
command: []string{"SADD", "SaddKey4"}, command: []string{"SADD", "SaddKey4"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -176,7 +176,7 @@ func Test_HandleSCARD(t *testing.T) {
command: []string{"SCARD"}, command: []string{"SCARD"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Command too long { // 5. Command too long
preset: false, preset: false,
@@ -184,7 +184,7 @@ func Test_HandleSCARD(t *testing.T) {
command: []string{"SCARD", "ScardKey5", "ScardKey5"}, command: []string{"SCARD", "ScardKey5", "ScardKey5"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -286,7 +286,7 @@ func Test_HandleSDIFF(t *testing.T) {
preset: false, preset: false,
command: []string{"SDIFF"}, command: []string{"SDIFF"},
expectedResponse: []string{}, expectedResponse: []string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -404,7 +404,7 @@ func Test_HandleSDIFFSTORE(t *testing.T) {
preset: false, preset: false,
command: []string{"SDIFFSTORE", "SdiffStoreDestination6"}, command: []string{"SDIFFSTORE", "SdiffStoreDestination6"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -523,7 +523,7 @@ func Test_HandleSINTER(t *testing.T) {
preset: false, preset: false,
command: []string{"SINTER"}, command: []string{"SINTER"},
expectedResponse: []string{}, expectedResponse: []string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -640,7 +640,7 @@ func Test_HandleSINTERCARD(t *testing.T) {
preset: false, preset: false,
command: []string{"SINTERCARD"}, command: []string{"SINTERCARD"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -756,7 +756,7 @@ func Test_HandleSINTERSTORE(t *testing.T) {
preset: false, preset: false,
command: []string{"SINTERSTORE", "SinterStoreDestination6"}, command: []string{"SINTERSTORE", "SinterStoreDestination6"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -848,14 +848,14 @@ func Test_HandleSISMEMBER(t *testing.T) {
key: "SIsMemberKey4", key: "SIsMemberKey4",
command: []string{"SISMEMBER", "SIsMemberKey4"}, command: []string{"SISMEMBER", "SIsMemberKey4"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Command too long { // 5. Command too long
preset: false, preset: false,
key: "SIsMemberKey5", key: "SIsMemberKey5",
command: []string{"SISMEMBER", "SIsMemberKey5", "one", "two", "three"}, command: []string{"SISMEMBER", "SIsMemberKey5", "one", "two", "three"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -929,13 +929,13 @@ func Test_HandleSMEMBERS(t *testing.T) {
preset: false, preset: false,
command: []string{"SMEMBERS"}, command: []string{"SMEMBERS"},
expectedResponse: []string{}, expectedResponse: []string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Command too long { // 5. Command too long
preset: false, preset: false,
command: []string{"SMEMBERS", "SmembersKey5", "SmembersKey6"}, command: []string{"SMEMBERS", "SmembersKey5", "SmembersKey6"},
expectedResponse: []string{}, expectedResponse: []string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1019,7 +1019,7 @@ func Test_HandleSMISMEMBER(t *testing.T) {
key: "SmismemberKey4", key: "SmismemberKey4",
command: []string{"SMISMEMBER", "SmismemberKey4"}, command: []string{"SMISMEMBER", "SmismemberKey4"},
expectedResponse: nil, expectedResponse: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1127,12 +1127,12 @@ func Test_HandleSMOVE(t *testing.T) {
{ // 5. Command too short { // 5. Command too short
preset: false, preset: false,
command: []string{"SMOVE", "SmoveSource5", "SmoveSource6"}, command: []string{"SMOVE", "SmoveSource5", "SmoveSource6"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 6. Command too long { // 6. Command too long
preset: false, preset: false,
command: []string{"SMOVE", "SmoveSource5", "SmoveSource6", "member1", "member2"}, command: []string{"SMOVE", "SmoveSource5", "SmoveSource6", "member1", "member2"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1224,12 +1224,12 @@ func Test_HandleSPOP(t *testing.T) {
{ // 3. Command too short { // 3. Command too short
preset: false, preset: false,
command: []string{"SPOP"}, command: []string{"SPOP"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 4. Command too long { // 4. Command too long
preset: false, preset: false,
command: []string{"SPOP", "SpopSource5", "SpopSource6", "member1", "member2"}, command: []string{"SPOP", "SpopSource5", "SpopSource6", "member1", "member2"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Throw error when count is not an integer { // 5. Throw error when count is not an integer
preset: false, preset: false,
@@ -1337,12 +1337,12 @@ func Test_HandleSRANDMEMBER(t *testing.T) {
{ // 4. Command too short { // 4. Command too short
preset: false, preset: false,
command: []string{"SRANDMEMBER"}, command: []string{"SRANDMEMBER"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Command too long { // 5. Command too long
preset: false, preset: false,
command: []string{"SRANDMEMBER", "SRandMemberSource5", "SRandMemberSource6", "member1", "member2"}, command: []string{"SRANDMEMBER", "SRandMemberSource5", "SRandMemberSource6", "member1", "member2"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 6. Throw error when count is not an integer { // 6. Throw error when count is not an integer
preset: false, preset: false,
@@ -1455,7 +1455,7 @@ func Test_HandleSREM(t *testing.T) {
{ // 4. Command too short { // 4. Command too short
preset: false, preset: false,
command: []string{"SREM", "SremKey"}, command: []string{"SREM", "SremKey"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1565,7 +1565,7 @@ func Test_HandleSUNION(t *testing.T) {
preset: false, preset: false,
command: []string{"SUNION"}, command: []string{"SUNION"},
expectedResponse: []string{}, expectedResponse: []string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1661,7 +1661,7 @@ func Test_HandleSUNIONSTORE(t *testing.T) {
preset: false, preset: false,
command: []string{"SUNIONSTORE", "SunionStoreDestination6"}, command: []string{"SUNIONSTORE", "SunionStoreDestination6"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }

View File

@@ -16,49 +16,49 @@ package set
import ( import (
"errors" "errors"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"slices" "slices"
"strings" "strings"
) )
func saddKeyFunc(cmd []string) ([]string, error) { func saddKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func scardKeyFunc(cmd []string) ([]string, error) { func scardKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func sdiffKeyFunc(cmd []string) ([]string, error) { func sdiffKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func sdiffstoreKeyFunc(cmd []string) ([]string, error) { func sdiffstoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func sinterKeyFunc(cmd []string) ([]string, error) { func sinterKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func sintercardKeyFunc(cmd []string) ([]string, error) { func sintercardKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
limitIdx := slices.IndexFunc(cmd, func(s string) bool { limitIdx := slices.IndexFunc(cmd, func(s string) bool {
@@ -74,70 +74,70 @@ func sintercardKeyFunc(cmd []string) ([]string, error) {
func sinterstoreKeyFunc(cmd []string) ([]string, error) { func sinterstoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func sismemberKeyFunc(cmd []string) ([]string, error) { func sismemberKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 3 { if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func smembersKeyFunc(cmd []string) ([]string, error) { func smembersKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func smismemberKeyFunc(cmd []string) ([]string, error) { func smismemberKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func smoveKeyFunc(cmd []string) ([]string, error) { func smoveKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:3], nil return cmd[1:3], nil
} }
func spopKeyFunc(cmd []string) ([]string, error) { func spopKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 || len(cmd) > 3 { if len(cmd) < 2 || len(cmd) > 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func srandmemberKeyFunc(cmd []string) ([]string, error) { func srandmemberKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 || len(cmd) > 3 { if len(cmd) < 2 || len(cmd) > 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func sremKeyFunc(cmd []string) ([]string, error) { func sremKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func sunionKeyFunc(cmd []string) ([]string, error) { func sunionKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func sunionstoreKeyFunc(cmd []string) ([]string, error) { func sunionstoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }

View File

@@ -21,7 +21,8 @@ import (
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/internal/sorted_set" "github.com/echovault/echovault/internal/sorted_set"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"math" "math"
"net" "net"
"slices" "slices"
@@ -29,7 +30,7 @@ import (
"strings" "strings"
) )
func handleZADD(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZADD(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zaddKeyFunc(cmd) keys, err := zaddKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -180,7 +181,7 @@ func handleZADD(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", set.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", set.Cardinality())), nil
} }
func handleZCARD(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZCARD(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zcardKeyFunc(cmd) keys, err := zcardKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -204,7 +205,7 @@ func handleZCARD(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", set.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", set.Cardinality())), nil
} }
func handleZCOUNT(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZCOUNT(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zcountKeyFunc(cmd) keys, err := zcountKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -272,7 +273,7 @@ func handleZCOUNT(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(fmt.Sprintf(":%d\r\n", len(members))), nil return []byte(fmt.Sprintf(":%d\r\n", len(members))), nil
} }
func handleZLEXCOUNT(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleZLEXCOUNT(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := zlexcountKeyFunc(cmd) keys, err := zlexcountKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -317,7 +318,7 @@ func handleZLEXCOUNT(ctx context.Context, cmd []string, server utils.EchoVault,
return []byte(fmt.Sprintf(":%d\r\n", count)), nil return []byte(fmt.Sprintf(":%d\r\n", count)), nil
} }
func handleZDIFF(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZDIFF(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zdiffKeyFunc(cmd) keys, err := zdiffKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -327,7 +328,7 @@ func handleZDIFF(ctx context.Context, cmd []string, server utils.EchoVault, conn
return strings.EqualFold(s, "withscores") return strings.EqualFold(s, "withscores")
}) })
if withscoresIndex > -1 && withscoresIndex < 2 { if withscoresIndex > -1 && withscoresIndex < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
locks := make(map[string]bool) locks := make(map[string]bool)
@@ -390,7 +391,7 @@ func handleZDIFF(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(res), nil return []byte(res), nil
} }
func handleZDIFFSTORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZDIFFSTORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zdiffstoreKeyFunc(cmd) keys, err := zdiffstoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -456,7 +457,7 @@ func handleZDIFFSTORE(ctx context.Context, cmd []string, server utils.EchoVault,
return []byte(fmt.Sprintf(":%d\r\n", diff.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", diff.Cardinality())), nil
} }
func handleZINCRBY(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZINCRBY(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zincrbyKeyFunc(cmd) keys, err := zincrbyKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -523,7 +524,7 @@ func handleZINCRBY(ctx context.Context, cmd []string, server utils.EchoVault, co
strconv.FormatFloat(float64(set.Get(member).Score), 'f', -1, 64))), nil strconv.FormatFloat(float64(set.Get(member).Score), 'f', -1, 64))), nil
} }
func handleZINTER(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZINTER(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zinterKeyFunc(cmd) keys, err := zinterKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -583,7 +584,7 @@ func handleZINTER(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(res), nil return []byte(res), nil
} }
func handleZINTERSTORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZINTERSTORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zinterstoreKeyFunc(cmd) keys, err := zinterstoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -650,7 +651,7 @@ func handleZINTERSTORE(ctx context.Context, cmd []string, server utils.EchoVault
return []byte(fmt.Sprintf(":%d\r\n", intersect.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", intersect.Cardinality())), nil
} }
func handleZMPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZMPOP(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zmpopKeyFunc(cmd) keys, err := zmpopKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -666,7 +667,7 @@ func handleZMPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn
}) })
if countIdx != -1 { if countIdx != -1 {
if countIdx < 2 { if countIdx < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
if countIdx == len(cmd)-1 { if countIdx == len(cmd)-1 {
return nil, errors.New("count must be a positive integer") return nil, errors.New("count must be a positive integer")
@@ -688,7 +689,7 @@ func handleZMPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn
}) })
if policyIdx != -1 { if policyIdx != -1 {
if policyIdx < 2 { if policyIdx < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
policy = strings.ToLower(cmd[policyIdx]) policy = strings.ToLower(cmd[policyIdx])
if modifierIdx == -1 || (policyIdx < modifierIdx) { if modifierIdx == -1 || (policyIdx < modifierIdx) {
@@ -728,7 +729,7 @@ func handleZMPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte("*0\r\n"), nil return []byte("*0\r\n"), nil
} }
func handleZPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZPOP(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zpopKeyFunc(cmd) keys, err := zpopKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -779,7 +780,7 @@ func handleZPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(res), nil return []byte(res), nil
} }
func handleZMSCORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZMSCORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zmscoreKeyFunc(cmd) keys, err := zmscoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -821,7 +822,7 @@ func handleZMSCORE(ctx context.Context, cmd []string, server utils.EchoVault, co
return []byte(res), nil return []byte(res), nil
} }
func handleZRANDMEMBER(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZRANDMEMBER(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zrandmemberKeyFunc(cmd) keys, err := zrandmemberKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -876,7 +877,7 @@ func handleZRANDMEMBER(ctx context.Context, cmd []string, server utils.EchoVault
return []byte(res), nil return []byte(res), nil
} }
func handleZRANK(ctx context.Context, cmd []string, server utils.EchoVault, _ *net.Conn) ([]byte, error) { func handleZRANK(ctx context.Context, cmd []string, server types.EchoVault, _ *net.Conn) ([]byte, error) {
keys, err := zrankKeyFunc(cmd) keys, err := zrankKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -926,7 +927,7 @@ func handleZRANK(ctx context.Context, cmd []string, server utils.EchoVault, _ *n
return []byte("$-1\r\n"), nil return []byte("$-1\r\n"), nil
} }
func handleZREM(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZREM(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zremKeyFunc(cmd) keys, err := zremKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -958,7 +959,7 @@ func handleZREM(ctx context.Context, cmd []string, server utils.EchoVault, conn
return []byte(fmt.Sprintf(":%d\r\n", deletedCount)), nil return []byte(fmt.Sprintf(":%d\r\n", deletedCount)), nil
} }
func handleZSCORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZSCORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zscoreKeyFunc(cmd) keys, err := zscoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -987,7 +988,7 @@ func handleZSCORE(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(fmt.Sprintf("$%d\r\n%s\r\n", len(score), score)), nil return []byte(fmt.Sprintf("$%d\r\n%s\r\n", len(score), score)), nil
} }
func handleZREMRANGEBYSCORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZREMRANGEBYSCORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zremrangebyscoreKeyFunc(cmd) keys, err := zremrangebyscoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1031,7 +1032,7 @@ func handleZREMRANGEBYSCORE(ctx context.Context, cmd []string, server utils.Echo
return []byte(fmt.Sprintf(":%d\r\n", deletedCount)), nil return []byte(fmt.Sprintf(":%d\r\n", deletedCount)), nil
} }
func handleZREMRANGEBYRANK(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZREMRANGEBYRANK(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zremrangebyrankKeyFunc(cmd) keys, err := zremrangebyrankKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1096,7 +1097,7 @@ func handleZREMRANGEBYRANK(ctx context.Context, cmd []string, server utils.EchoV
return []byte(fmt.Sprintf(":%d\r\n", deletedCount)), nil return []byte(fmt.Sprintf(":%d\r\n", deletedCount)), nil
} }
func handleZREMRANGEBYLEX(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZREMRANGEBYLEX(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zremrangebylexKeyFunc(cmd) keys, err := zremrangebylexKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1143,7 +1144,7 @@ func handleZREMRANGEBYLEX(ctx context.Context, cmd []string, server utils.EchoVa
return []byte(fmt.Sprintf(":%d\r\n", deletedCount)), nil return []byte(fmt.Sprintf(":%d\r\n", deletedCount)), nil
} }
func handleZRANGE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZRANGE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zrangeKeyCount(cmd) keys, err := zrangeKeyCount(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1283,7 +1284,7 @@ func handleZRANGE(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(res), nil return []byte(res), nil
} }
func handleZRANGESTORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZRANGESTORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zrangeStoreKeyFunc(cmd) keys, err := zrangeStoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1425,7 +1426,7 @@ func handleZRANGESTORE(ctx context.Context, cmd []string, server utils.EchoVault
return []byte(fmt.Sprintf(":%d\r\n", newSortedSet.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", newSortedSet.Cardinality())), nil
} }
func handleZUNION(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZUNION(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
if _, err := zunionKeyFunc(cmd); err != nil { if _, err := zunionKeyFunc(cmd); err != nil {
return nil, err return nil, err
} }
@@ -1479,7 +1480,7 @@ func handleZUNION(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(res), nil return []byte(res), nil
} }
func handleZUNIONSTORE(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleZUNIONSTORE(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := zunionstoreKeyFunc(cmd) keys, err := zunionstoreKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1545,12 +1546,12 @@ func handleZUNIONSTORE(ctx context.Context, cmd []string, server utils.EchoVault
return []byte(fmt.Sprintf(":%d\r\n", union.Cardinality())), nil return []byte(fmt.Sprintf(":%d\r\n", union.Cardinality())), nil
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "zadd", Command: "zadd",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.FastCategory},
Description: `(ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member...]) Description: `(ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member...])
Adds all the specified members with the specified scores to the sorted set at the key. Adds all the specified members with the specified scores to the sorted set at the key.
"NX" only adds the member if it currently does not exist in the sorted set. "NX" only adds the member if it currently does not exist in the sorted set.
@@ -1565,8 +1566,8 @@ Adds all the specified members with the specified scores to the sorted set at th
}, },
{ {
Command: "zcard", Command: "zcard",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZCARD key) Returns the set cardinality of the sorted set at key. Description: `(ZCARD key) Returns the set cardinality of the sorted set at key.
If the key does not exist, 0 is returned, otherwise the cardinality of the sorted set is returned. If the key does not exist, 0 is returned, otherwise the cardinality of the sorted set is returned.
If the key holds a value that is not a sorted set, this command will return an error.`, If the key holds a value that is not a sorted set, this command will return an error.`,
@@ -1576,8 +1577,8 @@ If the key holds a value that is not a sorted set, this command will return an e
}, },
{ {
Command: "zcount", Command: "zcount",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZCOUNT key min max) Description: `(ZCOUNT key min max)
Returns the number of elements in the sorted set key with scores in the range of min and max. Returns the number of elements in the sorted set key with scores in the range of min and max.
If the key does not exist, a count of 0 is returned, otherwise return the count. If the key does not exist, a count of 0 is returned, otherwise return the count.
@@ -1588,8 +1589,8 @@ If the key holds a value that is not a sorted set, an error is returned.`,
}, },
{ {
Command: "zdiff", Command: "zdiff",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZDIFF key [key...] [WITHSCORES]) Description: `(ZDIFF key [key...] [WITHSCORES])
Computes the difference between all the sorted sets specifies in the list of keys and returns the result.`, Computes the difference between all the sorted sets specifies in the list of keys and returns the result.`,
Sync: false, Sync: false,
@@ -1598,8 +1599,8 @@ Computes the difference between all the sorted sets specifies in the list of key
}, },
{ {
Command: "zdiffstore", Command: "zdiffstore",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZDIFFSTORE destination key [key...]). Description: `(ZDIFFSTORE destination key [key...]).
Computes the difference between all the sorted sets specifies in the list of keys. Stores the result in destination. Computes the difference between all the sorted sets specifies in the list of keys. Stores the result in destination.
If the base set (first key) does not exist, return 0, otherwise, return the cardinality of the diff.`, If the base set (first key) does not exist, return 0, otherwise, return the cardinality of the diff.`,
@@ -1609,8 +1610,8 @@ If the base set (first key) does not exist, return 0, otherwise, return the card
}, },
{ {
Command: "zincrby", Command: "zincrby",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.FastCategory},
Description: `(ZINCRBY key increment member). Description: `(ZINCRBY key increment member).
Increments the score of the specified sorted set's member by the increment. If the member does not exist, it is created. 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.`, If the key does not exist, it is created with new sorted set and the member added with the increment as its score.`,
@@ -1620,8 +1621,8 @@ If the key does not exist, it is created with new sorted set and the member adde
}, },
{ {
Command: "zinter", Command: "zinter",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZINTER key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]). Description: `(ZINTER key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]).
Computes the intersection of the sets in the keys, with weights, aggregate and scores`, Computes the intersection of the sets in the keys, with weights, aggregate and scores`,
Sync: false, Sync: false,
@@ -1630,8 +1631,8 @@ Computes the intersection of the sets in the keys, with weights, aggregate and s
}, },
{ {
Command: "zinterstore", Command: "zinterstore",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: ` Description: `
(ZINTERSTORE destination key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]). (ZINTERSTORE destination key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]).
Computes the intersection of the sets in the keys, with weights, aggregate and scores. The result is stored in destination.`, Computes the intersection of the sets in the keys, with weights, aggregate and scores. The result is stored in destination.`,
@@ -1641,8 +1642,8 @@ Computes the intersection of the sets in the keys, with weights, aggregate and s
}, },
{ {
Command: "zmpop", Command: "zmpop",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZMPOP key [key ...] <MIN | MAX> [COUNT count]) Description: `(ZMPOP key [key ...] <MIN | MAX> [COUNT count])
Pop a 'count' elements from sorted set. MIN or MAX determines whether to pop elements with the lowest or highest scores Pop a 'count' elements from sorted set. MIN or MAX determines whether to pop elements with the lowest or highest scores
respectively.`, respectively.`,
@@ -1652,8 +1653,8 @@ respectively.`,
}, },
{ {
Command: "zmscore", Command: "zmscore",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.FastCategory},
Description: `(ZMSCORE key member [member ...]) Description: `(ZMSCORE key member [member ...])
Returns the associated scores of the specified member in the sorted set. Returns the associated scores of the specified member in the sorted set.
Returns nil for members that do not exist in the set`, Returns nil for members that do not exist in the set`,
@@ -1663,8 +1664,8 @@ Returns nil for members that do not exist in the set`,
}, },
{ {
Command: "zpopmax", Command: "zpopmax",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZPOPMAX key [count]) Description: `(ZPOPMAX key [count])
Removes and returns 'count' number of members in the sorted set with the highest scores. Default count is 1.`, Removes and returns 'count' number of members in the sorted set with the highest scores. Default count is 1.`,
Sync: true, Sync: true,
@@ -1673,8 +1674,8 @@ Removes and returns 'count' number of members in the sorted set with the highest
}, },
{ {
Command: "zpopmin", Command: "zpopmin",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZPOPMIN key [count]) Description: `(ZPOPMIN key [count])
Removes and returns 'count' number of members in the sorted set with the lowest scores. Default count is 1.`, Removes and returns 'count' number of members in the sorted set with the lowest scores. Default count is 1.`,
Sync: true, Sync: true,
@@ -1683,8 +1684,8 @@ Removes and returns 'count' number of members in the sorted set with the lowest
}, },
{ {
Command: "zrandmember", Command: "zrandmember",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZRANDMEMBER key [count [WITHSCORES]]) Description: `(ZRANDMEMBER key [count [WITHSCORES]])
Return a list of length equivalent to count containing random members of the sorted set. Return 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. If count is negative, repeated elements are allowed. If count is positive, the returned elements will be distinct.
@@ -1695,8 +1696,8 @@ WITHSCORES modifies the result to include scores in the result.`,
}, },
{ {
Command: "zrank", Command: "zrank",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZRANK key member [WITHSCORE]) Description: `(ZRANK key member [WITHSCORE])
Returns the rank of the specified member in the sorted set. WITHSCORE modifies the result to also return the score.`, Returns the rank of the specified member in the sorted set. WITHSCORE modifies the result to also return the score.`,
Sync: false, Sync: false,
@@ -1705,8 +1706,8 @@ Returns the rank of the specified member in the sorted set. WITHSCORE modifies t
}, },
{ {
Command: "zrevrank", Command: "zrevrank",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZREVRANK key member [WITHSCORE]) Description: `(ZREVRANK key member [WITHSCORE])
Returns the rank of the member in the sorted set in reverse order. Returns the rank of the member in the sorted set in reverse order.
WITHSCORE modifies the result to include the score.`, WITHSCORE modifies the result to include the score.`,
@@ -1716,8 +1717,8 @@ WITHSCORE modifies the result to include the score.`,
}, },
{ {
Command: "zrem", Command: "zrem",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.FastCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.FastCategory},
Description: `(ZREM key member [member ...]) Removes the listed members from the sorted set. Description: `(ZREM key member [member ...]) Removes the listed members from the sorted set.
Returns the number of elements removed.`, Returns the number of elements removed.`,
Sync: true, Sync: true,
@@ -1726,8 +1727,8 @@ Returns the number of elements removed.`,
}, },
{ {
Command: "zscore", Command: "zscore",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.FastCategory},
Description: `(ZSCORE key member) Returns the score of the member in the sorted set.`, Description: `(ZSCORE key member) Returns the score of the member in the sorted set.`,
Sync: false, Sync: false,
KeyExtractionFunc: zscoreKeyFunc, KeyExtractionFunc: zscoreKeyFunc,
@@ -1735,8 +1736,8 @@ Returns the number of elements removed.`,
}, },
{ {
Command: "zremrangebylex", Command: "zremrangebylex",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZREMRANGEBYLEX key min max) Removes the elements in the lexicographical range between min and max`, Description: `(ZREMRANGEBYLEX key min max) Removes the elements in the lexicographical range between min and max`,
Sync: true, Sync: true,
KeyExtractionFunc: zremrangebylexKeyFunc, KeyExtractionFunc: zremrangebylexKeyFunc,
@@ -1744,8 +1745,8 @@ Returns the number of elements removed.`,
}, },
{ {
Command: "zremrangebyrank", Command: "zremrangebyrank",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZREMRANGEBYRANK key start stop) Removes the elements in the rank range between start and stop. Description: `(ZREMRANGEBYRANK key start stop) Removes the elements in the rank range between start and stop.
The elements are ordered from lowest score to highest score`, The elements are ordered from lowest score to highest score`,
Sync: true, Sync: true,
@@ -1754,8 +1755,8 @@ The elements are ordered from lowest score to highest score`,
}, },
{ {
Command: "zremrangebyscore", Command: "zremrangebyscore",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZREMRANGEBYSCORE key min max) Removes the elements whose scores are in the range between min and max`, Description: `(ZREMRANGEBYSCORE key min max) Removes the elements whose scores are in the range between min and max`,
Sync: true, Sync: true,
KeyExtractionFunc: zremrangebyscoreKeyFunc, KeyExtractionFunc: zremrangebyscoreKeyFunc,
@@ -1763,8 +1764,8 @@ The elements are ordered from lowest score to highest score`,
}, },
{ {
Command: "zlexcount", Command: "zlexcount",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZLEXCOUNT key min max) Returns the number of elements in within the sorted set within the Description: `(ZLEXCOUNT key min max) Returns the number of elements in within the sorted set within the
lexicographical range between min and max. Returns 0, if the keys does not exist or if all the members do not have lexicographical range between min and max. Returns 0, if the keys does not exist or if all the members do not have
the same score. If the value held at key is not a sorted set, an error is returned`, the same score. If the value held at key is not a sorted set, an error is returned`,
@@ -1774,8 +1775,8 @@ the same score. If the value held at key is not a sorted set, an error is return
}, },
{ {
Command: "zrange", Command: "zrange",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] Description: `(ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count]
[WITHSCORES]) Returns the range of elements in the sorted set`, [WITHSCORES]) Returns the range of elements in the sorted set`,
Sync: false, Sync: false,
@@ -1784,8 +1785,8 @@ the same score. If the value held at key is not a sorted set, an error is return
}, },
{ {
Command: "zrangestore", Command: "zrangestore",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `ZRANGESTORE destination source start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] Description: `ZRANGESTORE destination source start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count]
[WITHSCORES] Retrieve the range of elements in the sorted set and store it in destination`, [WITHSCORES] Retrieve the range of elements in the sorted set and store it in destination`,
Sync: true, Sync: true,
@@ -1794,8 +1795,8 @@ the same score. If the value held at key is not a sorted set, an error is return
}, },
{ {
Command: "zunion", Command: "zunion",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZUNION key [key ...] [WEIGHTS weight [weight ...]] Description: `(ZUNION key [key ...] [WEIGHTS weight [weight ...]]
[AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]) Return the union of the sorted sets in keys. The scores of each member of [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]) Return the union of the sorted sets in keys. The scores of each member of
a sorted set are multiplied by the corresponding weight in WEIGHTS. Aggregate determines how the scores are combined. a sorted set are multiplied by the corresponding weight in WEIGHTS. Aggregate determines how the scores are combined.
@@ -1806,8 +1807,8 @@ WITHSCORES option determines whether to return the result with scores included.`
}, },
{ {
Command: "zunionstore", Command: "zunionstore",
Module: utils.SortedSetModule, Module: constants.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZUNIONSTORE destination key [key ...] [WEIGHTS weight [weight ...]] Description: `(ZUNIONSTORE destination key [key ...] [WEIGHTS weight [weight ...]]
[AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]) Return the union of the sorted sets in keys. The scores of each member of [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]) Return the union of the sorted sets in keys. The scores of each member of
a sorted set are multiplied by the corresponding weight in WEIGHTS. Aggregate determines how the scores are combined. a sorted set are multiplied by the corresponding weight in WEIGHTS. Aggregate determines how the scores are combined.

View File

@@ -21,8 +21,8 @@ import (
"fmt" "fmt"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/internal/sorted_set" "github.com/echovault/echovault/internal/sorted_set"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"math" "math"
"slices" "slices"
@@ -36,7 +36,7 @@ func init() {
mockServer = echovault.NewEchoVault( mockServer = echovault.NewEchoVault(
echovault.WithConfig(config.Config{ echovault.WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
} }
@@ -226,7 +226,7 @@ func Test_HandleZADD(t *testing.T) {
command: []string{"ZADD", "ZaddKey11"}, command: []string{"ZADD", "ZaddKey11"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 12. Throw error when score/member entries are do not match { // 12. Throw error when score/member entries are do not match
preset: false, preset: false,
@@ -335,7 +335,7 @@ func Test_HandleZCARD(t *testing.T) {
command: []string{"ZCARD"}, command: []string{"ZCARD"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 4. Command too long { // 4. Command too long
preset: false, preset: false,
@@ -344,7 +344,7 @@ func Test_HandleZCARD(t *testing.T) {
command: []string{"ZCARD", "ZcardKey4", "ZcardKey5"}, command: []string{"ZCARD", "ZcardKey4", "ZcardKey5"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Return error when not a sorted set { // 5. Return error when not a sorted set
preset: true, preset: true,
@@ -476,7 +476,7 @@ func Test_HandleZCOUNT(t *testing.T) {
command: []string{"ZCOUNT"}, command: []string{"ZCOUNT"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 7. Command too long { // 7. Command too long
preset: false, preset: false,
@@ -485,7 +485,7 @@ func Test_HandleZCOUNT(t *testing.T) {
command: []string{"ZCOUNT", "ZcountKey4", "min", "max", "count"}, command: []string{"ZCOUNT", "ZcountKey4", "min", "max", "count"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 8. Throw error when value at the key is not a sorted set { // 8. Throw error when value at the key is not a sorted set
preset: true, preset: true,
@@ -600,7 +600,7 @@ func Test_HandleZLEXCOUNT(t *testing.T) {
command: []string{"ZLEXCOUNT"}, command: []string{"ZLEXCOUNT"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 6. Command too long { // 6. Command too long
preset: false, preset: false,
@@ -609,7 +609,7 @@ func Test_HandleZLEXCOUNT(t *testing.T) {
command: []string{"ZLEXCOUNT", "ZlexCountKey6", "min", "max", "count"}, command: []string{"ZLEXCOUNT", "ZlexCountKey6", "min", "max", "count"},
expectedValue: nil, expectedValue: nil,
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -762,7 +762,7 @@ func Test_HandleZDIFF(t *testing.T) {
preset: false, preset: false,
command: []string{"ZDIFF"}, command: []string{"ZDIFF"},
expectedResponse: [][]string{}, expectedResponse: [][]string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -939,7 +939,7 @@ func Test_HandleZDIFFSTORE(t *testing.T) {
preset: false, preset: false,
command: []string{"ZDIFFSTORE", "ZdiffStoreDestinationKey6"}, command: []string{"ZDIFFSTORE", "ZdiffStoreDestinationKey6"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1151,13 +1151,13 @@ func Test_HandleZINCRBY(t *testing.T) {
key: "ZincrbyKey11", key: "ZincrbyKey11",
command: []string{"ZINCRBY", "ZincrbyKey11", "one"}, command: []string{"ZINCRBY", "ZincrbyKey11", "one"},
expectedResponse: "", expectedResponse: "",
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 12. Command too long { // 12. Command too long
key: "ZincrbyKey12", key: "ZincrbyKey12",
command: []string{"ZINCRBY", "ZincrbyKey12", "one", "1", "2"}, command: []string{"ZINCRBY", "ZincrbyKey12", "one", "1", "2"},
expectedResponse: "", expectedResponse: "",
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1380,7 +1380,7 @@ func Test_HandleZMPOP(t *testing.T) {
{ // 9. Command too short { // 9. Command too short
preset: false, preset: false,
command: []string{"ZMPOP"}, command: []string{"ZMPOP"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1548,12 +1548,12 @@ func Test_HandleZPOP(t *testing.T) {
{ // 6. Command too short { // 6. Command too short
preset: false, preset: false,
command: []string{"ZPOPMAX"}, command: []string{"ZPOPMAX"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 7. Command too long { // 7. Command too long
preset: false, preset: false,
command: []string{"ZPOPMAX", "ZmpopMaxKey7", "6", "3"}, command: []string{"ZPOPMAX", "ZmpopMaxKey7", "6", "3"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1655,7 +1655,7 @@ func Test_HandleZMSCORE(t *testing.T) {
{ // 9. Command too short { // 9. Command too short
preset: false, preset: false,
command: []string{"ZMSCORE"}, command: []string{"ZMSCORE"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1752,12 +1752,12 @@ func Test_HandleZSCORE(t *testing.T) {
{ // 5. Command too short { // 5. Command too short
preset: false, preset: false,
command: []string{"ZSCORE"}, command: []string{"ZSCORE"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 6. Command too long { // 6. Command too long
preset: false, preset: false,
command: []string{"ZSCORE", "ZscoreKey5", "one", "two"}, command: []string{"ZSCORE", "ZscoreKey5", "one", "two"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -1859,12 +1859,12 @@ func Test_HandleZRANDMEMBER(t *testing.T) {
{ // 5. Command too short { // 5. Command too short
preset: false, preset: false,
command: []string{"ZRANDMEMBER"}, command: []string{"ZRANDMEMBER"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 6. Command too long { // 6. Command too long
preset: false, preset: false,
command: []string{"ZRANDMEMBER", "source5", "source6", "member1", "member2"}, command: []string{"ZRANDMEMBER", "source5", "source6", "member1", "member2"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 7. Throw error when count is not an integer { // 7. Throw error when count is not an integer
preset: false, preset: false,
@@ -2026,12 +2026,12 @@ func Test_HandleZRANK(t *testing.T) {
{ // 5. Command too short { // 5. Command too short
preset: false, preset: false,
command: []string{"ZRANK"}, command: []string{"ZRANK"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 6. Command too long { // 6. Command too long
preset: false, preset: false,
command: []string{"ZRANK", "ZrankKey5", "one", "WITHSCORES", "two"}, command: []string{"ZRANK", "ZrankKey5", "one", "WITHSCORES", "two"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -2131,7 +2131,7 @@ func Test_HandleZREM(t *testing.T) {
{ // 9. Command too short { // 9. Command too short
preset: false, preset: false,
command: []string{"ZREM"}, command: []string{"ZREM"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -2234,12 +2234,12 @@ func Test_HandleZREMRANGEBYSCORE(t *testing.T) {
{ // 4. Command too short { // 4. Command too short
preset: false, preset: false,
command: []string{"ZREMRANGEBYSCORE", "ZremRangeByScoreKey4", "3"}, command: []string{"ZREMRANGEBYSCORE", "ZremRangeByScoreKey4", "3"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Command too long { // 5. Command too long
preset: false, preset: false,
command: []string{"ZREMRANGEBYSCORE", "ZremRangeByScoreKey5", "4", "5", "8"}, command: []string{"ZREMRANGEBYSCORE", "ZremRangeByScoreKey5", "4", "5", "8"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -2364,7 +2364,7 @@ func Test_HandleZREMRANGEBYRANK(t *testing.T) {
{ // 4. Command too short { // 4. Command too short
preset: false, preset: false,
command: []string{"ZREMRANGEBYRANK", "ZremRangeByRankKey4", "3"}, command: []string{"ZREMRANGEBYRANK", "ZremRangeByRankKey4", "3"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Return error when start index is out of bounds { // 5. Return error when start index is out of bounds
preset: true, preset: true,
@@ -2401,7 +2401,7 @@ func Test_HandleZREMRANGEBYRANK(t *testing.T) {
{ // 7. Command too long { // 7. Command too long
preset: false, preset: false,
command: []string{"ZREMRANGEBYRANK", "ZremRangeByRankKey7", "4", "5", "8"}, command: []string{"ZREMRANGEBYRANK", "ZremRangeByRankKey7", "4", "5", "8"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -2529,12 +2529,12 @@ func Test_HandleZREMRANGEBYLEX(t *testing.T) {
{ // 4. Command too short { // 4. Command too short
preset: false, preset: false,
command: []string{"ZREMRANGEBYLEX", "ZremRangeByLexKey4", "a"}, command: []string{"ZREMRANGEBYLEX", "ZremRangeByLexKey4", "a"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 5. Command too long { // 5. Command too long
preset: false, preset: false,
command: []string{"ZREMRANGEBYLEX", "ZremRangeByLexKey5", "a", "b", "c"}, command: []string{"ZREMRANGEBYLEX", "ZremRangeByLexKey5", "a", "b", "c"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -2774,14 +2774,14 @@ func Test_HandleZRANGE(t *testing.T) {
presetValues: nil, presetValues: nil,
command: []string{"ZRANGE", "ZrangeKey15", "1"}, command: []string{"ZRANGE", "ZrangeKey15", "1"},
expectedResponse: [][]string{}, expectedResponse: [][]string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 16 Command too long { // 16 Command too long
preset: false, preset: false,
presetValues: nil, presetValues: nil,
command: []string{"ZRANGE", "ZrangeKey16", "a", "h", "BYLEX", "WITHSCORES", "LIMIT", "-4", "9", "REV", "WITHSCORES"}, command: []string{"ZRANGE", "ZrangeKey16", "a", "h", "BYLEX", "WITHSCORES", "LIMIT", "-4", "9", "REV", "WITHSCORES"},
expectedResponse: [][]string{}, expectedResponse: [][]string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -3058,14 +3058,14 @@ func Test_HandleZRANGESTORE(t *testing.T) {
presetValues: nil, presetValues: nil,
command: []string{"ZRANGESTORE", "ZrangeStoreKey15", "1"}, command: []string{"ZRANGESTORE", "ZrangeStoreKey15", "1"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 16 Command too long { // 16 Command too long
preset: false, preset: false,
presetValues: nil, presetValues: nil,
command: []string{"ZRANGESTORE", "ZrangeStoreDestinationKey16", "ZrangeStoreKey16", "a", "h", "BYLEX", "WITHSCORES", "LIMIT", "-4", "9", "REV", "WITHSCORES"}, command: []string{"ZRANGESTORE", "ZrangeStoreDestinationKey16", "ZrangeStoreKey16", "a", "h", "BYLEX", "WITHSCORES", "LIMIT", "-4", "9", "REV", "WITHSCORES"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -3341,7 +3341,7 @@ func Test_HandleZINTER(t *testing.T) {
}, },
command: []string{"ZINTER", "WEIGHTS", "5", "4"}, command: []string{"ZINTER", "WEIGHTS", "5", "4"},
expectedResponse: nil, expectedResponse: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 11. Throw an error if any of the provided keys are not sorted sets { // 11. Throw an error if any of the provided keys are not sorted sets
preset: true, preset: true,
@@ -3381,7 +3381,7 @@ func Test_HandleZINTER(t *testing.T) {
preset: false, preset: false,
command: []string{"ZINTER"}, command: []string{"ZINTER"},
expectedResponse: [][]string{}, expectedResponse: [][]string{},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -3688,7 +3688,7 @@ func Test_HandleZINTERSTORE(t *testing.T) {
}, },
command: []string{"ZINTERSTORE", "WEIGHTS", "5", "4"}, command: []string{"ZINTERSTORE", "WEIGHTS", "5", "4"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 11. Throw an error if any of the provided keys are not sorted sets { // 11. Throw an error if any of the provided keys are not sorted sets
preset: true, preset: true,
@@ -3728,7 +3728,7 @@ func Test_HandleZINTERSTORE(t *testing.T) {
preset: false, preset: false,
command: []string{"ZINTERSTORE"}, command: []string{"ZINTERSTORE"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -4029,7 +4029,7 @@ func Test_HandleZUNION(t *testing.T) {
}, },
command: []string{"ZUNION", "WEIGHTS", "5", "4"}, command: []string{"ZUNION", "WEIGHTS", "5", "4"},
expectedResponse: nil, expectedResponse: nil,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 11. Throw an error if any of the provided keys are not sorted sets { // 11. Throw an error if any of the provided keys are not sorted sets
preset: true, preset: true,
@@ -4071,7 +4071,7 @@ func Test_HandleZUNION(t *testing.T) {
{ // 13. Command too short { // 13. Command too short
preset: false, preset: false,
command: []string{"ZUNION"}, command: []string{"ZUNION"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -4410,7 +4410,7 @@ func Test_HandleZUNIONSTORE(t *testing.T) {
}, },
command: []string{"ZUNIONSTORE", "WEIGHTS", "5", "4"}, command: []string{"ZUNIONSTORE", "WEIGHTS", "5", "4"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // 11. Throw an error if any of the provided keys are not sorted sets { // 11. Throw an error if any of the provided keys are not sorted sets
preset: true, preset: true,
@@ -4457,7 +4457,7 @@ func Test_HandleZUNIONSTORE(t *testing.T) {
preset: false, preset: false,
command: []string{"ZUNIONSTORE"}, command: []string{"ZUNIONSTORE"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }

View File

@@ -16,35 +16,35 @@ package sorted_set
import ( import (
"errors" "errors"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"slices" "slices"
"strings" "strings"
) )
func zaddKeyFunc(cmd []string) ([]string, error) { func zaddKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 4 { if len(cmd) < 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zcardKeyFunc(cmd []string) ([]string, error) { func zcardKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:], nil return cmd[1:], nil
} }
func zcountKeyFunc(cmd []string) ([]string, error) { func zcountKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zdiffKeyFunc(cmd []string) ([]string, error) { func zdiffKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
withscoresIndex := slices.IndexFunc(cmd, func(s string) bool { withscoresIndex := slices.IndexFunc(cmd, func(s string) bool {
@@ -60,21 +60,21 @@ func zdiffKeyFunc(cmd []string) ([]string, error) {
func zdiffstoreKeyFunc(cmd []string) ([]string, error) { func zdiffstoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[2:], nil return cmd[2:], nil
} }
func zincrbyKeyFunc(cmd []string) ([]string, error) { func zincrbyKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zinterKeyFunc(cmd []string) ([]string, error) { func zinterKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
endIdx := slices.IndexFunc(cmd[1:], func(s string) bool { endIdx := slices.IndexFunc(cmd[1:], func(s string) bool {
if strings.EqualFold(s, "WEIGHTS") || if strings.EqualFold(s, "WEIGHTS") ||
@@ -90,12 +90,12 @@ func zinterKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 1 { if endIdx >= 1 {
return cmd[1:endIdx], nil return cmd[1:endIdx], nil
} }
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
func zinterstoreKeyFunc(cmd []string) ([]string, error) { func zinterstoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
endIdx := slices.IndexFunc(cmd[1:], func(s string) bool { endIdx := slices.IndexFunc(cmd[1:], func(s string) bool {
if strings.EqualFold(s, "WEIGHTS") || if strings.EqualFold(s, "WEIGHTS") ||
@@ -111,12 +111,12 @@ func zinterstoreKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 2 { if endIdx >= 2 {
return cmd[1:endIdx], nil return cmd[1:endIdx], nil
} }
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
func zmpopKeyFunc(cmd []string) ([]string, error) { func zmpopKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
endIdx := slices.IndexFunc(cmd, func(s string) bool { endIdx := slices.IndexFunc(cmd, func(s string) bool {
return slices.Contains([]string{"MIN", "MAX", "COUNT"}, strings.ToUpper(s)) return slices.Contains([]string{"MIN", "MAX", "COUNT"}, strings.ToUpper(s))
@@ -127,103 +127,103 @@ func zmpopKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 2 { if endIdx >= 2 {
return cmd[1:endIdx], nil return cmd[1:endIdx], nil
} }
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
func zmscoreKeyFunc(cmd []string) ([]string, error) { func zmscoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zpopKeyFunc(cmd []string) ([]string, error) { func zpopKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 || len(cmd) > 3 { if len(cmd) < 2 || len(cmd) > 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zrandmemberKeyFunc(cmd []string) ([]string, error) { func zrandmemberKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 || len(cmd) > 4 { if len(cmd) < 2 || len(cmd) > 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zrankKeyFunc(cmd []string) ([]string, error) { func zrankKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 || len(cmd) > 4 { if len(cmd) < 3 || len(cmd) > 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zremKeyFunc(cmd []string) ([]string, error) { func zremKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zrevrankKeyFunc(cmd []string) ([]string, error) { func zrevrankKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 { if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zscoreKeyFunc(cmd []string) ([]string, error) { func zscoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 3 { if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zremrangebylexKeyFunc(cmd []string) ([]string, error) { func zremrangebylexKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zremrangebyrankKeyFunc(cmd []string) ([]string, error) { func zremrangebyrankKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zremrangebyscoreKeyFunc(cmd []string) ([]string, error) { func zremrangebyscoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zlexcountKeyFunc(cmd []string) ([]string, error) { func zlexcountKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zrangeKeyCount(cmd []string) ([]string, error) { func zrangeKeyCount(cmd []string) ([]string, error) {
if len(cmd) < 4 || len(cmd) > 10 { if len(cmd) < 4 || len(cmd) > 10 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:2], nil return cmd[1:2], nil
} }
func zrangeStoreKeyFunc(cmd []string) ([]string, error) { func zrangeStoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 5 || len(cmd) > 11 { if len(cmd) < 5 || len(cmd) > 11 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return cmd[1:3], nil return cmd[1:3], nil
} }
func zunionKeyFunc(cmd []string) ([]string, error) { func zunionKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
endIdx := slices.IndexFunc(cmd[1:], func(s string) bool { endIdx := slices.IndexFunc(cmd[1:], func(s string) bool {
if strings.EqualFold(s, "WEIGHTS") || if strings.EqualFold(s, "WEIGHTS") ||
@@ -239,12 +239,12 @@ func zunionKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 1 { if endIdx >= 1 {
return cmd[1:endIdx], nil return cmd[1:endIdx], nil
} }
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
func zunionstoreKeyFunc(cmd []string) ([]string, error) { func zunionstoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 { if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
endIdx := slices.IndexFunc(cmd[1:], func(s string) bool { endIdx := slices.IndexFunc(cmd[1:], func(s string) bool {
if strings.EqualFold(s, "WEIGHTS") || if strings.EqualFold(s, "WEIGHTS") ||
@@ -260,5 +260,5 @@ func zunionstoreKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 1 { if endIdx >= 1 {
return cmd[1:endIdx], nil return cmd[1:endIdx], nil
} }
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }

View File

@@ -19,11 +19,12 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"net" "net"
) )
func handleSetRange(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSetRange(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := setRangeKeyFunc(cmd) keys, err := setRangeKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -98,7 +99,7 @@ func handleSetRange(ctx context.Context, cmd []string, server utils.EchoVault, c
return []byte(fmt.Sprintf(":%d\r\n", len(strRunes))), nil return []byte(fmt.Sprintf(":%d\r\n", len(strRunes))), nil
} }
func handleStrLen(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleStrLen(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := strLenKeyFunc(cmd) keys, err := strLenKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -124,7 +125,7 @@ func handleStrLen(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(fmt.Sprintf(":%d\r\n", len(value))), nil return []byte(fmt.Sprintf(":%d\r\n", len(value))), nil
} }
func handleSubStr(ctx context.Context, cmd []string, server utils.EchoVault, conn *net.Conn) ([]byte, error) { func handleSubStr(ctx context.Context, cmd []string, server types.EchoVault, conn *net.Conn) ([]byte, error) {
keys, err := subStrKeyFunc(cmd) keys, err := subStrKeyFunc(cmd)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -187,12 +188,12 @@ func handleSubStr(ctx context.Context, cmd []string, server utils.EchoVault, con
return []byte(fmt.Sprintf("$%d\r\n%s\r\n", len(str), str)), nil return []byte(fmt.Sprintf("$%d\r\n%s\r\n", len(str), str)), nil
} }
func Commands() []utils.Command { func Commands() []types.Command {
return []utils.Command{ return []types.Command{
{ {
Command: "setrange", Command: "setrange",
Module: utils.StringModule, Module: constants.StringModule,
Categories: []string{utils.StringCategory, utils.WriteCategory, utils.SlowCategory}, Categories: []string{constants.StringCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SETRANGE key offset value) Overwrites part of a string value with another by offset. Creates the key if it doesn't exist.", Description: "(SETRANGE key offset value) Overwrites part of a string value with another by offset. Creates the key if it doesn't exist.",
Sync: true, Sync: true,
KeyExtractionFunc: setRangeKeyFunc, KeyExtractionFunc: setRangeKeyFunc,
@@ -200,8 +201,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "strlen", Command: "strlen",
Module: utils.StringModule, Module: constants.StringModule,
Categories: []string{utils.StringCategory, utils.ReadCategory, utils.FastCategory}, Categories: []string{constants.StringCategory, constants.ReadCategory, constants.FastCategory},
Description: "(STRLEN key) Returns length of the key's value if it's a string.", Description: "(STRLEN key) Returns length of the key's value if it's a string.",
Sync: false, Sync: false,
KeyExtractionFunc: strLenKeyFunc, KeyExtractionFunc: strLenKeyFunc,
@@ -209,8 +210,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "substr", Command: "substr",
Module: utils.StringModule, Module: constants.StringModule,
Categories: []string{utils.StringCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.StringCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SUBSTR key start end) Returns a substring from the string value.", Description: "(SUBSTR key start end) Returns a substring from the string value.",
Sync: false, Sync: false,
KeyExtractionFunc: subStrKeyFunc, KeyExtractionFunc: subStrKeyFunc,
@@ -218,8 +219,8 @@ func Commands() []utils.Command {
}, },
{ {
Command: "getrange", Command: "getrange",
Module: utils.StringModule, Module: constants.StringModule,
Categories: []string{utils.StringCategory, utils.ReadCategory, utils.SlowCategory}, Categories: []string{constants.StringCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(GETRANGE key start end) Returns a substring from the string value.", Description: "(GETRANGE key start end) Returns a substring from the string value.",
Sync: false, Sync: false,
KeyExtractionFunc: subStrKeyFunc, KeyExtractionFunc: subStrKeyFunc,

View File

@@ -21,8 +21,8 @@ import (
"fmt" "fmt"
"github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal"
"github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault" "github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"strconv" "strconv"
"testing" "testing"
@@ -34,7 +34,7 @@ func init() {
mockServer = echovault.NewEchoVault( mockServer = echovault.NewEchoVault(
echovault.WithConfig(config.Config{ echovault.WithConfig(config.Config{
DataDir: "", DataDir: "",
EvictionPolicy: utils.NoEviction, EvictionPolicy: constants.NoEviction,
}), }),
) )
} }
@@ -121,13 +121,13 @@ func Test_HandleSetRange(t *testing.T) {
preset: false, preset: false,
command: []string{"SETRANGE", "key"}, command: []string{"SETRANGE", "key"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Command too long { // Command too long
preset: false, preset: false,
command: []string{"SETRANGE", "key", "offset", "value", "value1"}, command: []string{"SETRANGE", "key", "offset", "value", "value1"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -210,7 +210,7 @@ func Test_HandleStrLen(t *testing.T) {
presetValue: "", presetValue: "",
command: []string{"STRLEN"}, command: []string{"STRLEN"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Too many args { // Too many args
preset: false, preset: false,
@@ -218,7 +218,7 @@ func Test_HandleStrLen(t *testing.T) {
presetValue: "", presetValue: "",
command: []string{"STRLEN", "StrLenKey4", "StrLenKey5"}, command: []string{"STRLEN", "StrLenKey4", "StrLenKey5"},
expectedResponse: 0, expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
} }
@@ -316,12 +316,12 @@ func Test_HandleSubStr(t *testing.T) {
}, },
{ // Command too short { // Command too short
command: []string{"SUBSTR", "key", "10"}, command: []string{"SUBSTR", "key", "10"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ {
// Command too long // Command too long
command: []string{"SUBSTR", "key", "10", "15", "20"}, command: []string{"SUBSTR", "key", "10", "15", "20"},
expectedError: errors.New(utils.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
{ // Start index is not an integer { // Start index is not an integer
command: []string{"SUBSTR", "key", "start", "10"}, command: []string{"SUBSTR", "key", "start", "10"},

View File

@@ -16,26 +16,26 @@ package str
import ( import (
"errors" "errors"
"github.com/echovault/echovault/pkg/utils" "github.com/echovault/echovault/pkg/constants"
) )
func setRangeKeyFunc(cmd []string) ([]string, error) { func setRangeKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func strLenKeyFunc(cmd []string) ([]string, error) { func strLenKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 { if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }
func subStrKeyFunc(cmd []string) ([]string, error) { func subStrKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 { if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse) return nil, errors.New(constants.WrongArgsResponse)
} }
return []string{cmd[1]}, nil return []string{cmd[1]}, nil
} }

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package utils package types
import ( import (
"context" "context"