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"
"fmt"
"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"
"gopkg.in/yaml.v3"
"log"
@@ -285,7 +286,7 @@ func (acl *ACL) AuthenticateConnection(_ context.Context, conn *net.Conn, cmd []
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()
defer acl.RUnlockUsers()
@@ -298,7 +299,7 @@ func (acl *ACL) AuthorizeConnection(conn *net.Conn, cmd []string, command utils.
return err
}
if !reflect.DeepEqual(subCommand, utils.SubCommand{}) {
if !reflect.DeepEqual(subCommand, types.SubCommand{}) {
comm = fmt.Sprintf("%s|%s", comm, subCommand.Command)
categories = append(categories, subCommand.Categories...)
keys, err = subCommand.KeyExtractionFunc(cmd)
@@ -380,7 +381,7 @@ func (acl *ACL) AuthorizeConnection(conn *net.Conn, cmd []string, command utils.
}
// 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
channel := keys[0]
// 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
if slices.Contains(categories, utils.ReadCategory) {
if slices.Contains(categories, constants.ReadCategory) {
if !slices.ContainsFunc(keys, func(key string) bool {
return slices.ContainsFunc(connection.User.IncludedReadKeys, func(readKeyGlob string) bool {
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
if slices.Contains(categories, utils.WriteCategory) {
if slices.Contains(categories, constants.WriteCategory) {
if !slices.ContainsFunc(keys, func(key string) bool {
return slices.ContainsFunc(connection.User.IncludedWriteKeys, func(writeKeyGlob string) bool {
if acl.GlobPatterns[writeKeyGlob].Match(key) {

View File

@@ -20,7 +20,7 @@ import (
"flag"
"fmt"
"github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"log"
"os"
"path"
@@ -108,7 +108,7 @@ There is no limit by default.`, func(memory string) error {
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:
1) noeviction - Do not evict any keys even when max-memory is exceeded.
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.
7) volatile-random - Evict random keys with an expiration.`, func(policy string) error {
policies := []string{
utils.NoEviction,
utils.AllKeysLFU, utils.AllKeysLRU, utils.AllKeysRandom,
utils.VolatileLFU, utils.VolatileLRU, utils.VolatileRandom,
constants.NoEviction,
constants.AllKeysLFU, constants.AllKeysLRU, constants.AllKeysRandom,
constants.VolatileLFU, constants.VolatileLRU, constants.VolatileRandom,
}
policyIdx := slices.Index(policies, strings.ToLower(policy))
if policyIdx == -1 {

View File

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

View File

@@ -20,7 +20,7 @@ import (
"fmt"
"github.com/echovault/echovault/internal"
"github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/types"
"github.com/hashicorp/raft"
"io"
"log"
@@ -29,9 +29,9 @@ import (
type FSMOpts struct {
Config config.Config
EchoVault utils.EchoVault
EchoVault types.EchoVault
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
}
@@ -94,7 +94,7 @@ func (fsm *FSM) Apply(log *raft.Log) interface{} {
handler := command.HandlerFunc
subCommand, ok := internal.GetSubCommand(command, request.CMD).(utils.SubCommand)
subCommand, ok := internal.GetSubCommand(command, request.CMD).(types.SubCommand)
if ok {
handler = subCommand.HandlerFunc
}

View File

@@ -27,16 +27,16 @@ import (
"path/filepath"
"time"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/types"
"github.com/hashicorp/raft"
raftboltdb "github.com/hashicorp/raft-boltdb"
)
type Opts struct {
Config config.Config
EchoVault utils.EchoVault
EchoVault types.EchoVault
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
}

View File

@@ -20,7 +20,8 @@ import (
"cmp"
"errors"
"fmt"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"io"
"log"
"math/big"
@@ -128,7 +129,7 @@ func GetIPAddress() (string, error) {
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 {
return nil
}
@@ -140,8 +141,8 @@ func GetSubCommand(command utils.Command, cmd []string) interface{} {
return nil
}
func IsWriteCommand(command utils.Command, subCommand utils.SubCommand) bool {
return slices.Contains(append(command.Categories, subCommand.Categories...), utils.WriteCategory)
func IsWriteCommand(command types.Command, subCommand types.SubCommand) bool {
return slices.Contains(append(command.Categories, subCommand.Categories...), constants.WriteCategory)
}
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/sorted_set"
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
func All() []utils.Command {
var commands []utils.Command
func All() []types.Command {
var commands []types.Command
commands = append(commands, acl.Commands()...)
commands = append(commands, admin.Commands()...)
commands = append(commands, generic.Commands()...)

View File

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

View File

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

View File

@@ -18,7 +18,7 @@ import (
"fmt"
"github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/pkg/commands"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"reflect"
"testing"
)
@@ -28,7 +28,7 @@ func TestEchoVault_LLEN(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -87,7 +87,7 @@ func TestEchoVault_LINDEX(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -187,7 +187,7 @@ func TestEchoVault_LMOVE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -359,7 +359,7 @@ func TestEchoVault_POP(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -431,7 +431,7 @@ func TestEchoVault_LPUSH(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -508,7 +508,7 @@ func TestEchoVault_RPUSH(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -565,7 +565,7 @@ func TestEchoVault_LRANGE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -686,7 +686,7 @@ func TestEchoVault_LREM(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -753,7 +753,7 @@ func TestEchoVault_LSET(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -860,7 +860,7 @@ func TestEchoVault_LTRIM(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
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/set"
"github.com/echovault/echovault/pkg/commands"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"reflect"
"slices"
"testing"
@@ -29,7 +29,7 @@ func TestEchoVault_SADD(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -88,7 +88,7 @@ func TestEchoVault_SCARD(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -143,7 +143,7 @@ func TestEchoVault_SDIFF(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -237,7 +237,7 @@ func TestEchoVault_SDIFFSTORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -332,7 +332,7 @@ func TestEchoVault_SINTER(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -426,7 +426,7 @@ func TestEchoVault_SINTERCARD(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -532,7 +532,7 @@ func TestEchoVault_SINTERSTORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -627,7 +627,7 @@ func TestEchoVault_SISMEMBER(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -686,7 +686,7 @@ func TestEchoVault_SMEMBERS(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -746,7 +746,7 @@ func TestEchoVault_SMISMEMBER(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -824,7 +824,7 @@ func TestEchoVault_SMOVE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -910,7 +910,7 @@ func TestEchoVault_SPOP(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -963,7 +963,7 @@ func TestEchoVault_SRANDMEMBER(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1032,7 +1032,7 @@ func TestEchoVault_SREM(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1091,7 +1091,7 @@ func TestEchoVault_SUNION(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1178,7 +1178,7 @@ func TestEchoVault_SUNIONSTORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
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/sorted_set"
"github.com/echovault/echovault/pkg/commands"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"math"
"reflect"
"strconv"
@@ -31,7 +31,7 @@ func TestEchoVault_ZADD(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -257,7 +257,7 @@ func TestEchoVault_ZCARD(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -320,7 +320,7 @@ func TestEchoVault_ZCOUNT(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -421,7 +421,7 @@ func TestEchoVault_ZDIFF(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -573,7 +573,7 @@ func TestEchoVault_ZDIFFSTORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -694,7 +694,7 @@ func TestEchoVault_ZINCRBY(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -844,7 +844,7 @@ func TestEchoVault_ZINTER(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1157,7 +1157,7 @@ func TestEchoVault_ZINTERSTORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1484,7 +1484,7 @@ func TestEchoVault_ZLEXCOUNT(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1577,7 +1577,7 @@ func TestEchoVault_ZMPOP(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1733,7 +1733,7 @@ func TestEchoVault_ZMSCORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1814,7 +1814,7 @@ func TestEchoVault_ZPOP(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1922,7 +1922,7 @@ func TestEchoVault_ZRANDMEMBER(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -1998,7 +1998,7 @@ func TestEchoVault_ZRANGE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -2163,7 +2163,7 @@ func TestEchoVault_ZRANGESTORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -2377,7 +2377,7 @@ func TestEchoVault_ZRANK(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -2476,7 +2476,7 @@ func TestEchoVault_ZREM(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -2547,7 +2547,7 @@ func TestEchoVault_ZREMRANGEBYSCORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -2619,7 +2619,7 @@ func TestEchoVault_ZSCORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -2699,7 +2699,7 @@ func TestEchoVault_ZUNION(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
@@ -3037,7 +3037,7 @@ func TestEchoVault_ZUNIONSTORE(t *testing.T) {
WithCommands(commands.All()),
WithConfig(config.Config{
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/raft"
"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"
"log"
"net"
@@ -69,7 +70,7 @@ type EchoVault struct {
}
// 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.
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) {
echovault.commands = commands
}
@@ -109,7 +110,7 @@ func WithCommands(commands []utils.Command) func(echovault *EchoVault) {
func NewEchoVault(options ...func(echovault *EchoVault)) *EchoVault {
echovault := &EchoVault{
context: context.Background(),
commands: make([]utils.Command, 0),
commands: make([]types.Command, 0),
config: config.DefaultConfig(),
store: make(map[string]internal.KeyData),
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 echovault.config.EvictionPolicy != utils.NoEviction {
if echovault.config.EvictionPolicy != constants.NoEviction {
go func() {
for {
<-time.After(echovault.config.EvictionInterval)

View File

@@ -19,7 +19,7 @@ import (
"errors"
"fmt"
"github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"log"
"math/rand"
"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.
// If the key exists, the existing key is locked.
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")
}
@@ -166,7 +166,7 @@ func (server *EchoVault) GetValue(ctx context.Context, key string) interface{} {
// This count triggers a snapshot when the threshold is reached.
// The key must be locked prior to calling this function.
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")
}
@@ -276,9 +276,9 @@ func (server *EchoVault) DeleteKey(ctx context.Context, key string) error {
// Remove the key from the cache.
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)
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)
}
@@ -299,21 +299,21 @@ func (server *EchoVault) updateKeyInCache(ctx context.Context, key string) error
return nil
}
switch strings.ToLower(server.config.EvictionPolicy) {
case utils.AllKeysLFU:
case constants.AllKeysLFU:
server.lfuCache.mutex.Lock()
defer server.lfuCache.mutex.Unlock()
server.lfuCache.cache.Update(key)
case utils.AllKeysLRU:
case constants.AllKeysLRU:
server.lruCache.mutex.Lock()
defer server.lruCache.mutex.Unlock()
server.lruCache.cache.Update(key)
case utils.VolatileLFU:
case constants.VolatileLFU:
server.lfuCache.mutex.Lock()
defer server.lfuCache.mutex.Unlock()
if server.store[key].ExpireAt != (time.Time{}) {
server.lfuCache.cache.Update(key)
}
case utils.VolatileLRU:
case constants.VolatileLRU:
server.lruCache.mutex.Lock()
defer server.lruCache.mutex.Unlock()
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
// we're below the max memory limit.
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
// until the LFU cache is empty.
server.lfuCache.mutex.Lock()
@@ -382,7 +382,7 @@ func (server *EchoVault) adjustMemoryUsage(ctx context.Context) error {
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
// until the LRU cache is empty.
server.lruCache.mutex.Lock()
@@ -415,7 +415,7 @@ func (server *EchoVault) adjustMemoryUsage(ctx context.Context) error {
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
// or there are no more keys remaining.
for {
@@ -449,7 +449,7 @@ func (server *EchoVault) adjustMemoryUsage(ctx context.Context) error {
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
// or there are no more keys with expiry time.
for {

View File

@@ -19,12 +19,13 @@ import (
"errors"
"fmt"
"github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"net"
"strings"
)
func (server *EchoVault) GetAllCommands() []utils.Command {
func (server *EchoVault) GetAllCommands() []types.Command {
return server.commands
}
@@ -36,13 +37,13 @@ func (server *EchoVault) GetPubSub() interface{} {
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 {
if strings.EqualFold(command.Command, cmd) {
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) {
@@ -59,7 +60,7 @@ func (server *EchoVault) handleCommand(ctx context.Context, message []byte, conn
synchronize := command.Sync
handler := command.HandlerFunc
subCommand, ok := internal.GetSubCommand(command, cmd).(utils.SubCommand)
subCommand, ok := internal.GetSubCommand(command, cmd).(types.SubCommand)
if ok {
synchronize = subCommand.Sync
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
if server.config.ForwardCommand {
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")

View File

@@ -20,7 +20,8 @@ import (
"errors"
"fmt"
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"
"log"
"net"
@@ -30,9 +31,9 @@ import (
"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 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
acl, ok := server.GetACL().(*internal_acl.ACL)
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 {
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 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
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
}
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 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
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]))
}
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)
if !ok {
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
}
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)
if !ok {
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 {
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 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
acl, ok := server.GetACL().(*internal_acl.ACL)
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 {
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)
if !ok {
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
}
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 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
acl, ok := server.GetACL().(*internal_acl.ACL)
if !ok {
@@ -364,9 +365,9 @@ func handleList(_ context.Context, cmd []string, server utils.EchoVault, _ *net.
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 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
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 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
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 []byte(utils.OkResponse), nil
return []byte(constants.OkResponse), nil
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "auth",
Module: utils.ACLModule,
Categories: []string{utils.ConnectionCategory, utils.SlowCategory},
Module: constants.ACLModule,
Categories: []string{constants.ConnectionCategory, constants.SlowCategory},
Description: "(AUTH [username] password) Authenticates the connection",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -504,18 +505,18 @@ func Commands() []utils.Command {
},
{
Command: "acl",
Module: utils.ACLModule,
Module: constants.ACLModule,
Categories: []string{},
Description: "Access-Control-List commands",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
SubCommands: []utils.SubCommand{
SubCommands: []types.SubCommand{
{
Command: "cat",
Module: utils.ACLModule,
Categories: []string{utils.SlowCategory},
Module: constants.ACLModule,
Categories: []string{constants.SlowCategory},
Description: `(ACL CAT [category]) List all the categories.
If the optional category is provided, list all the commands in the category`,
Sync: false,
@@ -526,8 +527,8 @@ If the optional category is provided, list all the commands in the category`,
},
{
Command: "users",
Module: utils.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.ACLModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL USERS) List all usernames of the configured ACL users",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -537,8 +538,8 @@ If the optional category is provided, list all the commands in the category`,
},
{
Command: "setuser",
Module: utils.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.ACLModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL SETUSER) Configure a new or existing user",
Sync: true,
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",
Module: utils.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.ACLModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL GETUSER username) List the ACL rules of a user",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -559,8 +560,8 @@ If the optional category is provided, list all the commands in the category`,
},
{
Command: "deluser",
Module: utils.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.ACLModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL DELUSER username [username ...]) Deletes users and terminates their connections. Cannot delete default user",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -570,8 +571,8 @@ If the optional category is provided, list all the commands in the category`,
},
{
Command: "whoami",
Module: utils.ACLModule,
Categories: []string{utils.FastCategory},
Module: constants.ACLModule,
Categories: []string{constants.FastCategory},
Description: "(ACL WHOAMI) Returns the authenticated user of the current connection",
Sync: true,
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",
Module: utils.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.ACLModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL LIST) Dumps effective acl rules in acl config file format",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
@@ -592,8 +593,8 @@ If the optional category is provided, list all the commands in the category`,
},
{
Command: "load",
Module: utils.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.ACLModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: `
(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.
@@ -606,8 +607,8 @@ When 'REPLACE' is passed, users from config file who share a username with users
},
{
Command: "save",
Module: utils.ACLModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.ACLModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(ACL SAVE) Saves the effective ACL rules the configured ACL config file",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {

View File

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

View File

@@ -18,14 +18,15 @@ import (
"context"
"errors"
"fmt"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"github.com/gobwas/glob"
"net"
"slices"
"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()
res := ""
@@ -70,7 +71,7 @@ func handleGetAllCommands(ctx context.Context, cmd []string, server utils.EchoVa
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
commands := server.GetAllCommands()
@@ -87,7 +88,7 @@ func handleCommandCount(_ context.Context, _ []string, server utils.EchoVault, _
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) {
case 2:
// 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)
return []byte(res), nil
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
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "commands",
Module: utils.AdminModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory},
Module: constants.AdminModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory},
Description: "Get a list of all the commands in available on the echovault with categories and descriptions",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
@@ -203,18 +204,18 @@ func Commands() []utils.Command {
},
{
Command: "command",
Module: utils.AdminModule,
Module: constants.AdminModule,
Categories: []string{},
Description: "Commands pertaining to echovault commands",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
return []string{}, nil
},
SubCommands: []utils.SubCommand{
SubCommands: []types.SubCommand{
{
Command: "docs",
Module: utils.AdminModule,
Categories: []string{utils.SlowCategory, utils.ConnectionCategory},
Module: constants.AdminModule,
Categories: []string{constants.SlowCategory, constants.ConnectionCategory},
Description: "Get command documentation",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
@@ -222,8 +223,8 @@ func Commands() []utils.Command {
},
{
Command: "count",
Module: utils.AdminModule,
Categories: []string{utils.SlowCategory},
Module: constants.AdminModule,
Categories: []string{constants.SlowCategory},
Description: "Get the dumber of commands in the echovault",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
@@ -231,8 +232,8 @@ func Commands() []utils.Command {
},
{
Command: "list",
Module: utils.AdminModule,
Categories: []string{utils.SlowCategory},
Module: constants.AdminModule,
Categories: []string{constants.SlowCategory},
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.`,
Sync: false,
@@ -243,30 +244,30 @@ Allows for filtering by ACL category or glob pattern.`,
},
{
Command: "save",
Module: utils.AdminModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.AdminModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(SAVE) Trigger a snapshot save",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
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 {
return nil, err
}
return []byte(utils.OkResponse), nil
return []byte(constants.OkResponse), nil
},
},
{
Command: "lastsave",
Module: utils.AdminModule,
Categories: []string{utils.AdminCategory, utils.FastCategory, utils.DangerousCategory},
Module: constants.AdminModule,
Categories: []string{constants.AdminCategory, constants.FastCategory, constants.DangerousCategory},
Description: "(LASTSAVE) Get unix timestamp for the latest snapshot in milliseconds.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
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()
if msec == 0 {
return nil, errors.New("no snapshot")
@@ -276,18 +277,18 @@ Allows for filtering by ACL category or glob pattern.`,
},
{
Command: "rewriteaof",
Module: utils.AdminModule,
Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory},
Module: constants.AdminModule,
Categories: []string{constants.AdminCategory, constants.SlowCategory, constants.DangerousCategory},
Description: "(REWRITEAOF) Trigger re-writing of append process",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
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 {
return nil, err
}
return []byte(utils.OkResponse), nil
return []byte(constants.OkResponse), nil
},
},
}

View File

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

View File

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

View File

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

View File

@@ -20,7 +20,8 @@ import (
"flag"
"fmt"
"github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"log"
"net"
"strconv"
@@ -48,7 +49,7 @@ type KeyObject struct {
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)
if err != nil {
return nil, err
@@ -56,7 +57,7 @@ func handleSet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
key := keys[0]
value := cmd[2]
res := []byte(utils.OkResponse)
res := []byte(constants.OkResponse)
params, err := getSetCommandParams(cmd[3:], SetParams{})
if err != nil {
@@ -112,7 +113,7 @@ func handleSet(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
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 {
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -240,7 +241,7 @@ func handleMGet(ctx context.Context, cmd []string, server utils.EchoVault, _ *ne
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -284,7 +285,7 @@ func handlePersist(ctx context.Context, cmd []string, server utils.EchoVault, _
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -418,7 +419,7 @@ func handleExpire(ctx context.Context, cmd []string, server utils.EchoVault, _ *
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)
if err != nil {
return nil, err
@@ -486,12 +487,12 @@ func handleExpireAt(ctx context.Context, cmd []string, server utils.EchoVault, _
return []byte(":1\r\n"), nil
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "set",
Module: utils.GenericModule,
Categories: []string{utils.WriteCategory, utils.SlowCategory},
Module: constants.GenericModule,
Categories: []string{constants.WriteCategory, constants.SlowCategory},
Description: `
(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.
@@ -508,8 +509,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
},
{
Command: "mset",
Module: utils.GenericModule,
Categories: []string{utils.WriteCategory, utils.SlowCategory},
Module: constants.GenericModule,
Categories: []string{constants.WriteCategory, constants.SlowCategory},
Description: "(MSET key value [key value ...]) Automatically generic or modify multiple key/value pairs.",
Sync: true,
KeyExtractionFunc: msetKeyFunc,
@@ -517,8 +518,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
},
{
Command: "get",
Module: utils.GenericModule,
Categories: []string{utils.ReadCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.ReadCategory, constants.FastCategory},
Description: "(GET key) Get the value at the specified key.",
Sync: false,
KeyExtractionFunc: getKeyFunc,
@@ -526,8 +527,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
},
{
Command: "mget",
Module: utils.GenericModule,
Categories: []string{utils.ReadCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.ReadCategory, constants.FastCategory},
Description: "(MGET key [key ...]) Get multiple values from the specified keys.",
Sync: false,
KeyExtractionFunc: mgetKeyFunc,
@@ -535,8 +536,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
},
{
Command: "del",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: "(DEL key [key ...]) Removes one or more keys from the store.",
Sync: true,
KeyExtractionFunc: delKeyFunc,
@@ -544,8 +545,8 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
},
{
Command: "persist",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: `(PERSIST key) Removes the TTl associated with a key,
turning it from a volatile key to a persistent key.`,
Sync: true,
@@ -554,8 +555,8 @@ turning it from a volatile key to a persistent key.`,
},
{
Command: "expiretime",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.KeyspaceCategory, constants.ReadCategory, constants.FastCategory},
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.
Returns -2 if the key does not exist.`,
@@ -565,8 +566,8 @@ Returns -2 if the key does not exist.`,
},
{
Command: "pexpiretime",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.KeyspaceCategory, constants.ReadCategory, constants.FastCategory},
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.
Returns -2 if the key does not exist.`,
@@ -576,8 +577,8 @@ Returns -2 if the key does not exist.`,
},
{
Command: "ttl",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.GenericModule,
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.
If the key exists but does not have an associated expiry time, -1 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",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.GenericModule,
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.
If the key exists but does not have an associated expiry time, -1 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",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
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.
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",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
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.
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",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: `(EXPIREAT key unix-time-seconds [NX | XX | GT | LT])
Expire the key in at the exact unix time in seconds.
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",
Module: utils.GenericModule,
Categories: []string{utils.KeyspaceCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.GenericModule,
Categories: []string{constants.KeyspaceCategory, constants.WriteCategory, constants.FastCategory},
Description: `(PEXPIREAT key unix-time-milliseconds [NX | XX | GT | LT])
Expire the key in at the exact unix time in milliseconds.
This commands turns a key into a volatile one.

View File

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

View File

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

View File

@@ -19,7 +19,8 @@ import (
"errors"
"fmt"
"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"
"net"
"slices"
@@ -27,7 +28,7 @@ import (
"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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -136,7 +137,7 @@ func handleHGET(ctx context.Context, cmd []string, server utils.EchoVault, _ *ne
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)
if err != nil {
return nil, err
@@ -187,7 +188,7 @@ func handleHSTRLEN(ctx context.Context, cmd []string, server utils.EchoVault, co
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)
if err != nil {
return nil, err
@@ -228,7 +229,7 @@ func handleHVALS(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
return nil, err
@@ -344,7 +345,7 @@ func handleHRANDFIELD(ctx context.Context, cmd []string, server utils.EchoVault,
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -399,7 +400,7 @@ func handleHKEYS(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -531,7 +532,7 @@ func handleHGETALL(ctx context.Context, cmd []string, server utils.EchoVault, co
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)
if err != nil {
return nil, err
@@ -561,7 +562,7 @@ func handleHEXISTS(ctx context.Context, cmd []string, server utils.EchoVault, co
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)
if err != nil {
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
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "hset",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.HashModule,
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`,
Sync: true,
KeyExtractionFunc: hsetKeyFunc,
@@ -613,8 +614,8 @@ func Commands() []utils.Command {
},
{
Command: "hsetnx",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.HashModule,
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`,
Sync: true,
KeyExtractionFunc: hsetnxKeyFunc,
@@ -622,8 +623,8 @@ func Commands() []utils.Command {
},
{
Command: "hget",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.HashModule,
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`,
Sync: false,
KeyExtractionFunc: hgetKeyFunc,
@@ -631,8 +632,8 @@ func Commands() []utils.Command {
},
{
Command: "hstrlen",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HSTRLEN key field [field ...])
Return the string length of the values stored at the specified fields. 0 if the value does not exist`,
Sync: false,
@@ -641,8 +642,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hvals",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(HVALS key) Returns all the values of the hash at key.`,
Sync: false,
KeyExtractionFunc: hvalsKeyFunc,
@@ -650,8 +651,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hrandfield",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(HRANDFIELD key [count [WITHVALUES]]) Returns one or more random fields from the hash`,
Sync: false,
KeyExtractionFunc: hrandfieldKeyFunc,
@@ -659,8 +660,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hlen",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HLEN key) Returns the number of fields in the hash`,
Sync: false,
KeyExtractionFunc: hlenKeyFunc,
@@ -668,8 +669,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hkeys",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(HKEYS key) Returns all the fields in a hash`,
Sync: false,
KeyExtractionFunc: hkeysKeyFunc,
@@ -677,8 +678,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hincrbyfloat",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.WriteCategory, constants.FastCategory},
Description: `(HINCRBYFLOAT key field increment) Increment the hash value by the float increment`,
Sync: true,
KeyExtractionFunc: hincrbyKeyFunc,
@@ -686,8 +687,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hincrby",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.WriteCategory, constants.FastCategory},
Description: `(HINCRBY key field increment) Increment the hash value by the integer increment`,
Sync: true,
KeyExtractionFunc: hincrbyKeyFunc,
@@ -695,8 +696,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hgetall",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(HGETALL key) Get all fields and values of a hash`,
Sync: false,
KeyExtractionFunc: hgetallKeyFunc,
@@ -704,8 +705,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hexists",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HEXISTS key field) Returns if field is an existing field in the hash`,
Sync: false,
KeyExtractionFunc: hexistsKeyFunc,
@@ -713,8 +714,8 @@ Return the string length of the values stored at the specified fields. 0 if the
},
{
Command: "hdel",
Module: utils.HashModule,
Categories: []string{utils.HashCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.HashModule,
Categories: []string{constants.HashCategory, constants.ReadCategory, constants.FastCategory},
Description: `(HDEL key field [field ...]) Deletes the specified fields from the hash`,
Sync: true,
KeyExtractionFunc: hdelKeyFunc,

View File

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

View File

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

View File

@@ -19,14 +19,15 @@ import (
"errors"
"fmt"
"github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"math"
"net"
"slices"
"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)
if err != nil {
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")
}
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -164,7 +165,7 @@ func handleLRange(ctx context.Context, cmd []string, server utils.EchoVault, con
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)
if err != nil {
return nil, err
@@ -200,10 +201,10 @@ func handleLSet(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
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 {
return nil, err
}
return []byte(utils.OkResponse), nil
return []byte(constants.OkResponse), nil
}
if err = server.SetValue(ctx, key, list[start:end]); err != nil {
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)
if err != nil {
return nil, err
@@ -317,10 +318,10 @@ func handleLRem(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
return nil, err
@@ -378,10 +379,10 @@ func handleLMove(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
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 {
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)
if err != nil {
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 {
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)
if err != nil {
return nil, err
@@ -511,12 +512,12 @@ func handlePop(ctx context.Context, cmd []string, server utils.EchoVault, _ *net
}
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "lpush",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.ListModule,
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.",
Sync: true,
KeyExtractionFunc: lpushKeyFunc,
@@ -524,8 +525,8 @@ func Commands() []utils.Command {
},
{
Command: "lpushx",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.ListModule,
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.",
Sync: true,
KeyExtractionFunc: lpushKeyFunc,
@@ -533,8 +534,8 @@ func Commands() []utils.Command {
},
{
Command: "lpop",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.ListModule,
Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(LPOP key) Removes and returns the first element of a list.",
Sync: true,
KeyExtractionFunc: popKeyFunc,
@@ -542,8 +543,8 @@ func Commands() []utils.Command {
},
{
Command: "llen",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.ListModule,
Categories: []string{constants.ListCategory, constants.ReadCategory, constants.FastCategory},
Description: "(LLEN key) Return the length of a list.",
Sync: false,
KeyExtractionFunc: llenKeyFunc,
@@ -551,8 +552,8 @@ func Commands() []utils.Command {
},
{
Command: "lrange",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.ListModule,
Categories: []string{constants.ListCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(LRANGE key start end) Return a range of elements between the given indices.",
Sync: false,
KeyExtractionFunc: lrangeKeyFunc,
@@ -560,8 +561,8 @@ func Commands() []utils.Command {
},
{
Command: "lindex",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.ListModule,
Categories: []string{constants.ListCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(LINDEX key index) Gets list element by index.",
Sync: false,
KeyExtractionFunc: lindexKeyFunc,
@@ -569,8 +570,8 @@ func Commands() []utils.Command {
},
{
Command: "lset",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.ListModule,
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.",
Sync: true,
KeyExtractionFunc: lsetKeyFunc,
@@ -578,8 +579,8 @@ func Commands() []utils.Command {
},
{
Command: "ltrim",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.ListModule,
Categories: []string{constants.ListCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(LTRIM key start end) Trims a list to the specified range.",
Sync: true,
KeyExtractionFunc: ltrimKeyFunc,
@@ -587,8 +588,8 @@ func Commands() []utils.Command {
},
{
Command: "lrem",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.ListModule,
Categories: []string{constants.ListCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(LREM key count element) Remove elements from list.",
Sync: true,
KeyExtractionFunc: lremKeyFunc,
@@ -596,8 +597,8 @@ func Commands() []utils.Command {
},
{
Command: "lmove",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.ListModule,
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.",
Sync: true,
KeyExtractionFunc: lmoveKeyFunc,
@@ -605,8 +606,8 @@ func Commands() []utils.Command {
},
{
Command: "rpop",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.ListModule,
Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(RPOP key) Removes and gets the last element in a list.",
Sync: true,
KeyExtractionFunc: popKeyFunc,
@@ -614,8 +615,8 @@ func Commands() []utils.Command {
},
{
Command: "rpush",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.ListModule,
Categories: []string{constants.ListCategory, constants.WriteCategory, constants.FastCategory},
Description: "(RPUSH key element [element ...]) Appends one or multiple elements to the end of a list.",
Sync: true,
KeyExtractionFunc: rpushKeyFunc,
@@ -623,8 +624,8 @@ func Commands() []utils.Command {
},
{
Command: "rpushx",
Module: utils.ListModule,
Categories: []string{utils.ListCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.ListModule,
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.",
Sync: true,
KeyExtractionFunc: rpushKeyFunc,

View File

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

View File

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

View File

@@ -19,12 +19,13 @@ import (
"errors"
"fmt"
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"
"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)
if !ok {
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:]
if len(channels) == 0 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
withPattern := strings.EqualFold(cmd[0], "psubscribe")
@@ -42,7 +43,7 @@ func handleSubscribe(ctx context.Context, cmd []string, server utils.EchoVault,
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)
if !ok {
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
}
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)
if !ok {
return nil, errors.New("could not load pubsub module")
}
if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
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 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
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
}
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)
if !ok {
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
}
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)
if !ok {
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
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "subscribe",
Module: utils.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.ConnectionCategory, utils.SlowCategory},
Module: constants.PubSubModule,
Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory},
Description: "(SUBSCRIBE channel [channel ...]) Subscribe to one or more channels.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the channels as keys
if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:], nil
},
@@ -121,14 +122,14 @@ func Commands() []utils.Command {
},
{
Command: "psubscribe",
Module: utils.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.ConnectionCategory, utils.SlowCategory},
Module: constants.PubSubModule,
Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory},
Description: "(PSUBSCRIBE pattern [pattern ...]) Subscribe to one or more glob patterns.",
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the patterns as keys
if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:], nil
},
@@ -136,14 +137,14 @@ func Commands() []utils.Command {
},
{
Command: "publish",
Module: utils.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.FastCategory},
Module: constants.PubSubModule,
Categories: []string{constants.PubSubCategory, constants.FastCategory},
Description: "(PUBLISH channel message) Publish a message to the specified channel.",
Sync: true,
KeyExtractionFunc: func(cmd []string) ([]string, error) {
// Treat the channel as a key
if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return []string{cmd[1]}, nil
},
@@ -151,8 +152,8 @@ func Commands() []utils.Command {
},
{
Command: "unsubscribe",
Module: utils.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.ConnectionCategory, utils.SlowCategory},
Module: constants.PubSubModule,
Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory},
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
it's currently subscribe to.`,
@@ -165,8 +166,8 @@ it's currently subscribe to.`,
},
{
Command: "punsubscribe",
Module: utils.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.ConnectionCategory, utils.SlowCategory},
Module: constants.PubSubModule,
Categories: []string{constants.PubSubCategory, constants.ConnectionCategory, constants.SlowCategory},
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
it's currently subscribe to.`,
@@ -179,19 +180,19 @@ it's currently subscribe to.`,
},
{
Command: "pubsub",
Module: utils.PubSubModule,
Module: constants.PubSubModule,
Categories: []string{},
Description: "",
Sync: false,
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")
},
SubCommands: []utils.SubCommand{
SubCommands: []types.SubCommand{
{
Command: "channels",
Module: utils.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.SlowCategory},
Module: constants.PubSubModule,
Categories: []string{constants.PubSubCategory, constants.SlowCategory},
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
channels with 1 or more subscribers.`,
@@ -201,8 +202,8 @@ channels with 1 or more subscribers.`,
},
{
Command: "numpat",
Module: utils.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.SlowCategory},
Module: constants.PubSubModule,
Categories: []string{constants.PubSubCategory, constants.SlowCategory},
Description: `(PUBSUB NUMPAT) Return the number of patterns that are currently subscribed to by clients.`,
Sync: false,
KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil },
@@ -210,8 +211,8 @@ channels with 1 or more subscribers.`,
},
{
Command: "numsub",
Module: utils.PubSubModule,
Categories: []string{utils.PubSubCategory, utils.SlowCategory},
Module: constants.PubSubModule,
Categories: []string{constants.PubSubCategory, constants.SlowCategory},
Description: `(PUBSUB NUMSUB [channel [channel ...]]) Return an array of arrays containing the provided
channel name and how many clients are currently subscribed to the channel.`,
Sync: false,

View File

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

View File

@@ -20,13 +20,14 @@ import (
"fmt"
"github.com/echovault/echovault/internal"
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"
"slices"
"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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -151,7 +152,7 @@ func handleSDIFF(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
return nil, err
@@ -227,7 +228,7 @@ func handleSDIFFSTORE(ctx context.Context, cmd []string, server utils.EchoVault,
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)
if err != nil {
return nil, err
@@ -282,7 +283,7 @@ func handleSINTER(ctx context.Context, cmd []string, server utils.EchoVault, con
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)
if err != nil {
return nil, err
@@ -294,7 +295,7 @@ func handleSINTERCARD(ctx context.Context, cmd []string, server utils.EchoVault,
return strings.EqualFold(s, "limit")
})
if limitIdx >= 0 && limitIdx < 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
if 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
}
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -436,7 +437,7 @@ func handleSISMEMBER(ctx context.Context, cmd []string, server utils.EchoVault,
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)
if err != nil {
return nil, err
@@ -471,7 +472,7 @@ func handleSMEMBERS(ctx context.Context, cmd []string, server utils.EchoVault, c
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)
if err != nil {
return nil, err
@@ -514,7 +515,7 @@ func handleSMISMEMBER(ctx context.Context, cmd []string, server utils.EchoVault,
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -612,7 +613,7 @@ func handleSPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
return nil, err
@@ -656,7 +657,7 @@ func handleSRANDMEMBER(ctx context.Context, cmd []string, server utils.EchoVault
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -735,7 +736,7 @@ func handleSUNION(ctx context.Context, cmd []string, server utils.EchoVault, con
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)
if err != nil {
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
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "sadd",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.SetModule,
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.",
Sync: true,
KeyExtractionFunc: saddKeyFunc,
@@ -807,8 +808,8 @@ func Commands() []utils.Command {
},
{
Command: "scard",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.WriteCategory, constants.FastCategory},
Description: "(SCARD key) Returns the cardinality of the set.",
Sync: false,
KeyExtractionFunc: scardKeyFunc,
@@ -816,8 +817,8 @@ func Commands() []utils.Command {
},
{
Command: "sdiff",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
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.
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",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SetModule,
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'.
Returns the cardinality of the new set`,
Sync: true,
@@ -837,8 +838,8 @@ Returns the cardinality of the new set`,
},
{
Command: "sinter",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SINTER key [key...]) Returns the intersection of multiple sets.",
Sync: false,
KeyExtractionFunc: sinterKeyFunc,
@@ -846,8 +847,8 @@ Returns the cardinality of the new set`,
},
{
Command: "sintercard",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SINTERCARD key [key...] [LIMIT limit]) Returns the cardinality of the intersection between multiple sets.",
Sync: false,
KeyExtractionFunc: sintercardKeyFunc,
@@ -855,8 +856,8 @@ Returns the cardinality of the new set`,
},
{
Command: "sinterstore",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SINTERSTORE destination key [key...]) Stores the intersection of multiple sets at the destination key.",
Sync: true,
KeyExtractionFunc: sinterstoreKeyFunc,
@@ -864,8 +865,8 @@ Returns the cardinality of the new set`,
},
{
Command: "sismember",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.ReadCategory, constants.FastCategory},
Description: "(SISMEMBER key member) Returns if member is contained in the set.",
Sync: false,
KeyExtractionFunc: sismemberKeyFunc,
@@ -873,8 +874,8 @@ Returns the cardinality of the new set`,
},
{
Command: "smembers",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SMEMBERS key) Returns all members of a set.",
Sync: false,
KeyExtractionFunc: smembersKeyFunc,
@@ -882,8 +883,8 @@ Returns the cardinality of the new set`,
},
{
Command: "smismember",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.ReadCategory, constants.FastCategory},
Description: "(SMISMEMBER key member [member...]) Returns if multiple members are in the set.",
Sync: false,
KeyExtractionFunc: smismemberKeyFunc,
@@ -892,8 +893,8 @@ Returns the cardinality of the new set`,
{
Command: "smove",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.WriteCategory, constants.FastCategory},
Description: "(SMOVE source destination member) Moves a member from source set to destination set.",
Sync: true,
KeyExtractionFunc: smoveKeyFunc,
@@ -901,8 +902,8 @@ Returns the cardinality of the new set`,
},
{
Command: "spop",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SPOP key [count]) Returns and removes one or more random members from the set.",
Sync: true,
KeyExtractionFunc: spopKeyFunc,
@@ -910,8 +911,8 @@ Returns the cardinality of the new set`,
},
{
Command: "srandmember",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SRANDMEMBER key [count]) Returns one or more random members from the set without removing them.",
Sync: false,
KeyExtractionFunc: srandmemberKeyFunc,
@@ -919,8 +920,8 @@ Returns the cardinality of the new set`,
},
{
Command: "srem",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.WriteCategory, constants.FastCategory},
Description: "(SREM key member [member...]) Remove one or more members from a set.",
Sync: true,
KeyExtractionFunc: sremKeyFunc,
@@ -928,8 +929,8 @@ Returns the cardinality of the new set`,
},
{
Command: "sunion",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SetModule,
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.",
Sync: false,
KeyExtractionFunc: sunionKeyFunc,
@@ -937,8 +938,8 @@ Returns the cardinality of the new set`,
},
{
Command: "sunionstore",
Module: utils.SetModule,
Categories: []string{utils.SetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SetModule,
Categories: []string{constants.SetCategory, constants.WriteCategory, constants.SlowCategory},
Description: "(SUNIONSTORE destination key [key...]) Stores the union of the given sets into destination.",
Sync: true,
KeyExtractionFunc: sunionstoreKeyFunc,

View File

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

View File

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

View File

@@ -21,7 +21,8 @@ import (
"fmt"
"github.com/echovault/echovault/internal"
"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"
"net"
"slices"
@@ -29,7 +30,7 @@ import (
"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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -327,7 +328,7 @@ func handleZDIFF(ctx context.Context, cmd []string, server utils.EchoVault, conn
return strings.EqualFold(s, "withscores")
})
if withscoresIndex > -1 && withscoresIndex < 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
locks := make(map[string]bool)
@@ -390,7 +391,7 @@ func handleZDIFF(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -583,7 +584,7 @@ func handleZINTER(ctx context.Context, cmd []string, server utils.EchoVault, con
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -666,7 +667,7 @@ func handleZMPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn
})
if countIdx != -1 {
if countIdx < 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
if countIdx == len(cmd)-1 {
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 < 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
policy = strings.ToLower(cmd[policyIdx])
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
}
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)
if err != nil {
return nil, err
@@ -779,7 +780,7 @@ func handleZPOP(ctx context.Context, cmd []string, server utils.EchoVault, conn
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)
if err != nil {
return nil, err
@@ -821,7 +822,7 @@ func handleZMSCORE(ctx context.Context, cmd []string, server utils.EchoVault, co
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)
if err != nil {
return nil, err
@@ -876,7 +877,7 @@ func handleZRANDMEMBER(ctx context.Context, cmd []string, server utils.EchoVault
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)
if err != nil {
return nil, err
@@ -926,7 +927,7 @@ func handleZRANK(ctx context.Context, cmd []string, server utils.EchoVault, _ *n
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
return nil, err
@@ -1283,7 +1284,7 @@ func handleZRANGE(ctx context.Context, cmd []string, server utils.EchoVault, con
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)
if err != nil {
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
}
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 {
return nil, err
}
@@ -1479,7 +1480,7 @@ func handleZUNION(ctx context.Context, cmd []string, server utils.EchoVault, con
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)
if err != nil {
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
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "zadd",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.FastCategory},
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.
"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",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
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 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",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZCOUNT key min 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.
@@ -1588,8 +1589,8 @@ If the key holds a value that is not a sorted set, an error is returned.`,
},
{
Command: "zdiff",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZDIFF key [key...] [WITHSCORES])
Computes the difference between all the sorted sets specifies in the list of keys and returns the result.`,
Sync: false,
@@ -1598,8 +1599,8 @@ Computes the difference between all the sorted sets specifies in the list of key
},
{
Command: "zdiffstore",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZDIFFSTORE destination key [key...]).
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.`,
@@ -1609,8 +1610,8 @@ If the base set (first key) does not exist, return 0, otherwise, return the card
},
{
Command: "zincrby",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.FastCategory},
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.
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",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
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`,
Sync: false,
@@ -1630,8 +1631,8 @@ Computes the intersection of the sets in the keys, with weights, aggregate and s
},
{
Command: "zinterstore",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `
(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.`,
@@ -1641,8 +1642,8 @@ Computes the intersection of the sets in the keys, with weights, aggregate and s
},
{
Command: "zmpop",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
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
respectively.`,
@@ -1652,8 +1653,8 @@ respectively.`,
},
{
Command: "zmscore",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.FastCategory},
Description: `(ZMSCORE key member [member ...])
Returns the associated scores of the specified member in the sorted 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",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZPOPMAX key [count])
Removes and returns 'count' number of members in the sorted set with the highest scores. Default count is 1.`,
Sync: true,
@@ -1673,8 +1674,8 @@ Removes and returns 'count' number of members in the sorted set with the highest
},
{
Command: "zpopmin",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZPOPMIN key [count])
Removes and returns 'count' number of members in the sorted set with the lowest scores. Default count is 1.`,
Sync: true,
@@ -1683,8 +1684,8 @@ Removes and returns 'count' number of members in the sorted set with the lowest
},
{
Command: "zrandmember",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZRANDMEMBER key [count [WITHSCORES]])
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.
@@ -1695,8 +1696,8 @@ WITHSCORES modifies the result to include scores in the result.`,
},
{
Command: "zrank",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
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.`,
Sync: false,
@@ -1705,8 +1706,8 @@ Returns the rank of the specified member in the sorted set. WITHSCORE modifies t
},
{
Command: "zrevrank",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZREVRANK key member [WITHSCORE])
Returns the rank of the member in the sorted set in reverse order.
WITHSCORE modifies the result to include the score.`,
@@ -1716,8 +1717,8 @@ WITHSCORE modifies the result to include the score.`,
},
{
Command: "zrem",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.FastCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.FastCategory},
Description: `(ZREM key member [member ...]) Removes the listed members from the sorted set.
Returns the number of elements removed.`,
Sync: true,
@@ -1726,8 +1727,8 @@ Returns the number of elements removed.`,
},
{
Command: "zscore",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.FastCategory},
Description: `(ZSCORE key member) Returns the score of the member in the sorted set.`,
Sync: false,
KeyExtractionFunc: zscoreKeyFunc,
@@ -1735,8 +1736,8 @@ Returns the number of elements removed.`,
},
{
Command: "zremrangebylex",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
Description: `(ZREMRANGEBYLEX key min max) Removes the elements in the lexicographical range between min and max`,
Sync: true,
KeyExtractionFunc: zremrangebylexKeyFunc,
@@ -1744,8 +1745,8 @@ Returns the number of elements removed.`,
},
{
Command: "zremrangebyrank",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
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`,
Sync: true,
@@ -1754,8 +1755,8 @@ The elements are ordered from lowest score to highest score`,
},
{
Command: "zremrangebyscore",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
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`,
Sync: true,
KeyExtractionFunc: zremrangebyscoreKeyFunc,
@@ -1763,8 +1764,8 @@ The elements are ordered from lowest score to highest score`,
},
{
Command: "zlexcount",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
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
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`,
@@ -1774,8 +1775,8 @@ the same score. If the value held at key is not a sorted set, an error is return
},
{
Command: "zrange",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
Description: `(ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count]
[WITHSCORES]) Returns the range of elements in the sorted set`,
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",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
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`,
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",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.ReadCategory, constants.SlowCategory},
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
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",
Module: utils.SortedSetModule,
Categories: []string{utils.SortedSetCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.SortedSetModule,
Categories: []string{constants.SortedSetCategory, constants.WriteCategory, constants.SlowCategory},
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
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"
"github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/internal/sorted_set"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/echovault"
"github.com/echovault/echovault/pkg/utils"
"github.com/tidwall/resp"
"math"
"slices"
@@ -36,7 +36,7 @@ func init() {
mockServer = echovault.NewEchoVault(
echovault.WithConfig(config.Config{
DataDir: "",
EvictionPolicy: utils.NoEviction,
EvictionPolicy: constants.NoEviction,
}),
)
}
@@ -226,7 +226,7 @@ func Test_HandleZADD(t *testing.T) {
command: []string{"ZADD", "ZaddKey11"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 12. Throw error when score/member entries are do not match
preset: false,
@@ -335,7 +335,7 @@ func Test_HandleZCARD(t *testing.T) {
command: []string{"ZCARD"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 4. Command too long
preset: false,
@@ -344,7 +344,7 @@ func Test_HandleZCARD(t *testing.T) {
command: []string{"ZCARD", "ZcardKey4", "ZcardKey5"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 5. Return error when not a sorted set
preset: true,
@@ -476,7 +476,7 @@ func Test_HandleZCOUNT(t *testing.T) {
command: []string{"ZCOUNT"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 7. Command too long
preset: false,
@@ -485,7 +485,7 @@ func Test_HandleZCOUNT(t *testing.T) {
command: []string{"ZCOUNT", "ZcountKey4", "min", "max", "count"},
expectedValue: nil,
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
preset: true,
@@ -600,7 +600,7 @@ func Test_HandleZLEXCOUNT(t *testing.T) {
command: []string{"ZLEXCOUNT"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 6. Command too long
preset: false,
@@ -609,7 +609,7 @@ func Test_HandleZLEXCOUNT(t *testing.T) {
command: []string{"ZLEXCOUNT", "ZlexCountKey6", "min", "max", "count"},
expectedValue: nil,
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
}
@@ -762,7 +762,7 @@ func Test_HandleZDIFF(t *testing.T) {
preset: false,
command: []string{"ZDIFF"},
expectedResponse: [][]string{},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
}
@@ -939,7 +939,7 @@ func Test_HandleZDIFFSTORE(t *testing.T) {
preset: false,
command: []string{"ZDIFFSTORE", "ZdiffStoreDestinationKey6"},
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
}
@@ -1151,13 +1151,13 @@ func Test_HandleZINCRBY(t *testing.T) {
key: "ZincrbyKey11",
command: []string{"ZINCRBY", "ZincrbyKey11", "one"},
expectedResponse: "",
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 12. Command too long
key: "ZincrbyKey12",
command: []string{"ZINCRBY", "ZincrbyKey12", "one", "1", "2"},
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
preset: false,
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
preset: false,
command: []string{"ZPOPMAX"},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 7. Command too long
preset: false,
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
preset: false,
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
preset: false,
command: []string{"ZSCORE"},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 6. Command too long
preset: false,
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
preset: false,
command: []string{"ZRANDMEMBER"},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 6. Command too long
preset: false,
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
preset: false,
@@ -2026,12 +2026,12 @@ func Test_HandleZRANK(t *testing.T) {
{ // 5. Command too short
preset: false,
command: []string{"ZRANK"},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 6. Command too long
preset: false,
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
preset: false,
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
preset: false,
command: []string{"ZREMRANGEBYSCORE", "ZremRangeByScoreKey4", "3"},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 5. Command too long
preset: false,
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
preset: false,
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
preset: true,
@@ -2401,7 +2401,7 @@ func Test_HandleZREMRANGEBYRANK(t *testing.T) {
{ // 7. Command too long
preset: false,
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
preset: false,
command: []string{"ZREMRANGEBYLEX", "ZremRangeByLexKey4", "a"},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 5. Command too long
preset: false,
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,
command: []string{"ZRANGE", "ZrangeKey15", "1"},
expectedResponse: [][]string{},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 16 Command too long
preset: false,
presetValues: nil,
command: []string{"ZRANGE", "ZrangeKey16", "a", "h", "BYLEX", "WITHSCORES", "LIMIT", "-4", "9", "REV", "WITHSCORES"},
expectedResponse: [][]string{},
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
}
@@ -3058,14 +3058,14 @@ func Test_HandleZRANGESTORE(t *testing.T) {
presetValues: nil,
command: []string{"ZRANGESTORE", "ZrangeStoreKey15", "1"},
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
{ // 16 Command too long
preset: false,
presetValues: nil,
command: []string{"ZRANGESTORE", "ZrangeStoreDestinationKey16", "ZrangeStoreKey16", "a", "h", "BYLEX", "WITHSCORES", "LIMIT", "-4", "9", "REV", "WITHSCORES"},
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"},
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
preset: true,
@@ -3381,7 +3381,7 @@ func Test_HandleZINTER(t *testing.T) {
preset: false,
command: []string{"ZINTER"},
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"},
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
preset: true,
@@ -3728,7 +3728,7 @@ func Test_HandleZINTERSTORE(t *testing.T) {
preset: false,
command: []string{"ZINTERSTORE"},
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"},
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
preset: true,
@@ -4071,7 +4071,7 @@ func Test_HandleZUNION(t *testing.T) {
{ // 13. Command too short
preset: false,
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"},
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
preset: true,
@@ -4457,7 +4457,7 @@ func Test_HandleZUNIONSTORE(t *testing.T) {
preset: false,
command: []string{"ZUNIONSTORE"},
expectedResponse: 0,
expectedError: errors.New(utils.WrongArgsResponse),
expectedError: errors.New(constants.WrongArgsResponse),
},
}

View File

@@ -16,35 +16,35 @@ package sorted_set
import (
"errors"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"slices"
"strings"
)
func zaddKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zcardKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:], nil
}
func zcountKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zdiffKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
withscoresIndex := slices.IndexFunc(cmd, func(s string) bool {
@@ -60,21 +60,21 @@ func zdiffKeyFunc(cmd []string) ([]string, error) {
func zdiffstoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[2:], nil
}
func zincrbyKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zinterKeyFunc(cmd []string) ([]string, error) {
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 {
if strings.EqualFold(s, "WEIGHTS") ||
@@ -90,12 +90,12 @@ func zinterKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 1 {
return cmd[1:endIdx], nil
}
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
func zinterstoreKeyFunc(cmd []string) ([]string, error) {
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 {
if strings.EqualFold(s, "WEIGHTS") ||
@@ -111,12 +111,12 @@ func zinterstoreKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 2 {
return cmd[1:endIdx], nil
}
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
func zmpopKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
endIdx := slices.IndexFunc(cmd, func(s string) bool {
return slices.Contains([]string{"MIN", "MAX", "COUNT"}, strings.ToUpper(s))
@@ -127,103 +127,103 @@ func zmpopKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 2 {
return cmd[1:endIdx], nil
}
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
func zmscoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zpopKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 || len(cmd) > 3 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zrandmemberKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 2 || len(cmd) > 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zrankKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 || len(cmd) > 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zremKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zrevrankKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 3 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zscoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 3 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zremrangebylexKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zremrangebyrankKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zremrangebyscoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zlexcountKeyFunc(cmd []string) ([]string, error) {
if len(cmd) != 4 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zrangeKeyCount(cmd []string) ([]string, error) {
if len(cmd) < 4 || len(cmd) > 10 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:2], nil
}
func zrangeStoreKeyFunc(cmd []string) ([]string, error) {
if len(cmd) < 5 || len(cmd) > 11 {
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
return cmd[1:3], nil
}
func zunionKeyFunc(cmd []string) ([]string, error) {
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 {
if strings.EqualFold(s, "WEIGHTS") ||
@@ -239,12 +239,12 @@ func zunionKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 1 {
return cmd[1:endIdx], nil
}
return nil, errors.New(utils.WrongArgsResponse)
return nil, errors.New(constants.WrongArgsResponse)
}
func zunionstoreKeyFunc(cmd []string) ([]string, error) {
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 {
if strings.EqualFold(s, "WEIGHTS") ||
@@ -260,5 +260,5 @@ func zunionstoreKeyFunc(cmd []string) ([]string, error) {
if endIdx >= 1 {
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"
"fmt"
"github.com/echovault/echovault/internal"
"github.com/echovault/echovault/pkg/utils"
"github.com/echovault/echovault/pkg/constants"
"github.com/echovault/echovault/pkg/types"
"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)
if err != nil {
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
}
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)
if err != nil {
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
}
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)
if err != nil {
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
}
func Commands() []utils.Command {
return []utils.Command{
func Commands() []types.Command {
return []types.Command{
{
Command: "setrange",
Module: utils.StringModule,
Categories: []string{utils.StringCategory, utils.WriteCategory, utils.SlowCategory},
Module: constants.StringModule,
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.",
Sync: true,
KeyExtractionFunc: setRangeKeyFunc,
@@ -200,8 +201,8 @@ func Commands() []utils.Command {
},
{
Command: "strlen",
Module: utils.StringModule,
Categories: []string{utils.StringCategory, utils.ReadCategory, utils.FastCategory},
Module: constants.StringModule,
Categories: []string{constants.StringCategory, constants.ReadCategory, constants.FastCategory},
Description: "(STRLEN key) Returns length of the key's value if it's a string.",
Sync: false,
KeyExtractionFunc: strLenKeyFunc,
@@ -209,8 +210,8 @@ func Commands() []utils.Command {
},
{
Command: "substr",
Module: utils.StringModule,
Categories: []string{utils.StringCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.StringModule,
Categories: []string{constants.StringCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(SUBSTR key start end) Returns a substring from the string value.",
Sync: false,
KeyExtractionFunc: subStrKeyFunc,
@@ -218,8 +219,8 @@ func Commands() []utils.Command {
},
{
Command: "getrange",
Module: utils.StringModule,
Categories: []string{utils.StringCategory, utils.ReadCategory, utils.SlowCategory},
Module: constants.StringModule,
Categories: []string{constants.StringCategory, constants.ReadCategory, constants.SlowCategory},
Description: "(GETRANGE key start end) Returns a substring from the string value.",
Sync: false,
KeyExtractionFunc: subStrKeyFunc,

View File

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

View File

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

View File

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