mirror of
https://github.com/EchoVault/SugarDB.git
synced 2025-10-10 02:10:17 +08:00
Extracted KeyFuncs in etc module
This commit is contained in:
@@ -2,11 +2,9 @@ package etc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/echovault/echovault/src/utils"
|
"github.com/echovault/echovault/src/utils"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type KeyObject struct {
|
type KeyObject struct {
|
||||||
@@ -15,14 +13,12 @@ type KeyObject struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleSet(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
|
func handleSet(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
keys, err := setKeyFunc(cmd)
|
||||||
defer cancel()
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
switch x := len(cmd); {
|
key := keys[0]
|
||||||
default:
|
|
||||||
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
|
|
||||||
case x == 3:
|
|
||||||
key := cmd[1]
|
|
||||||
|
|
||||||
if !server.KeyExists(key) {
|
if !server.KeyExists(key) {
|
||||||
_, err := server.CreateKeyAndLock(ctx, key)
|
_, err := server.CreateKeyAndLock(ctx, key)
|
||||||
@@ -40,37 +36,34 @@ func handleSet(ctx context.Context, cmd []string, server utils.Server, conn *net
|
|||||||
|
|
||||||
server.SetValue(ctx, key, utils.AdaptType(cmd[2]))
|
server.SetValue(ctx, key, utils.AdaptType(cmd[2]))
|
||||||
server.KeyUnlock(key)
|
server.KeyUnlock(key)
|
||||||
|
|
||||||
return []byte(utils.OK_RESPONSE), nil
|
return []byte(utils.OK_RESPONSE), nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func handleSetNX(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
|
func handleSetNX(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
|
||||||
switch x := len(cmd); {
|
keys, err := setNXKeyFunc(cmd)
|
||||||
default:
|
if err != nil {
|
||||||
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
|
return nil, err
|
||||||
case x == 3:
|
}
|
||||||
key := cmd[1]
|
|
||||||
|
key := keys[0]
|
||||||
if server.KeyExists(key) {
|
if server.KeyExists(key) {
|
||||||
return nil, fmt.Errorf("key %s already exists", cmd[1])
|
return nil, fmt.Errorf("key %s already exists", key)
|
||||||
}
|
}
|
||||||
// TODO: Retry CreateKeyAndLock until we manage to obtain the key
|
// TODO: Retry CreateKeyAndLock until we manage to obtain the key
|
||||||
_, err := server.CreateKeyAndLock(ctx, key)
|
_, err = server.CreateKeyAndLock(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
server.SetValue(ctx, key, utils.AdaptType(cmd[2]))
|
server.SetValue(ctx, key, utils.AdaptType(cmd[2]))
|
||||||
server.KeyUnlock(key)
|
server.KeyUnlock(key)
|
||||||
}
|
|
||||||
return []byte(utils.OK_RESPONSE), nil
|
return []byte(utils.OK_RESPONSE), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMSet(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
|
func handleMSet(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) {
|
||||||
ctx, cancel := context.WithTimeout(ctx, 250*time.Millisecond)
|
if _, err := msetKeyFunc(cmd); err != nil {
|
||||||
defer cancel()
|
return nil, err
|
||||||
|
|
||||||
// Check if key/value pairs are complete
|
|
||||||
if len(cmd[1:])%2 != 0 {
|
|
||||||
return nil, errors.New("each key must have a matching value")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entries := make(map[string]KeyObject)
|
entries := make(map[string]KeyObject)
|
||||||
@@ -129,12 +122,7 @@ func Commands() []utils.Command {
|
|||||||
Categories: []string{utils.WriteCategory, utils.SlowCategory},
|
Categories: []string{utils.WriteCategory, utils.SlowCategory},
|
||||||
Description: "(SET key value) Set the value of a key, considering the value's type.",
|
Description: "(SET key value) Set the value of a key, considering the value's type.",
|
||||||
Sync: true,
|
Sync: true,
|
||||||
KeyExtractionFunc: func(cmd []string) ([]string, error) {
|
KeyExtractionFunc: setKeyFunc,
|
||||||
if len(cmd) != 3 {
|
|
||||||
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
|
|
||||||
}
|
|
||||||
return []string{cmd[1]}, nil
|
|
||||||
},
|
|
||||||
HandlerFunc: handleSet,
|
HandlerFunc: handleSet,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -142,12 +130,7 @@ func Commands() []utils.Command {
|
|||||||
Categories: []string{utils.WriteCategory, utils.SlowCategory},
|
Categories: []string{utils.WriteCategory, utils.SlowCategory},
|
||||||
Description: "(SETNX key value) Set the key/value only if the key doesn't exist.",
|
Description: "(SETNX key value) Set the key/value only if the key doesn't exist.",
|
||||||
Sync: true,
|
Sync: true,
|
||||||
KeyExtractionFunc: func(cmd []string) ([]string, error) {
|
KeyExtractionFunc: setNXKeyFunc,
|
||||||
if len(cmd) != 3 {
|
|
||||||
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
|
|
||||||
}
|
|
||||||
return []string{cmd[1]}, nil
|
|
||||||
},
|
|
||||||
HandlerFunc: handleSetNX,
|
HandlerFunc: handleSetNX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -155,18 +138,7 @@ func Commands() []utils.Command {
|
|||||||
Categories: []string{utils.WriteCategory, utils.SlowCategory},
|
Categories: []string{utils.WriteCategory, utils.SlowCategory},
|
||||||
Description: "(MSET key value [key value ...]) Automatically etc or modify multiple key/value pairs.",
|
Description: "(MSET key value [key value ...]) Automatically etc or modify multiple key/value pairs.",
|
||||||
Sync: true,
|
Sync: true,
|
||||||
KeyExtractionFunc: func(cmd []string) ([]string, error) {
|
KeyExtractionFunc: msetKeyFunc,
|
||||||
if len(cmd[1:])%2 != 0 {
|
|
||||||
return nil, errors.New("each key must be paired with a value")
|
|
||||||
}
|
|
||||||
var keys []string
|
|
||||||
for i, key := range cmd[1:] {
|
|
||||||
if i%2 == 0 {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keys, nil
|
|
||||||
},
|
|
||||||
HandlerFunc: handleMSet,
|
HandlerFunc: handleMSet,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -138,7 +138,7 @@ func Test_HandleMSET(t *testing.T) {
|
|||||||
command: []string{"SET", "test1", "value1", "test2", "10", "test3"},
|
command: []string{"SET", "test1", "value1", "test2", "10", "test3"},
|
||||||
expectedResponse: "",
|
expectedResponse: "",
|
||||||
expectedValues: make(map[string]interface{}),
|
expectedValues: make(map[string]interface{}),
|
||||||
expectedErr: errors.New("each key must have a matching value"),
|
expectedErr: errors.New("each key must be paired with a value"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
33
src/modules/etc/key_funcs.go
Normal file
33
src/modules/etc/key_funcs.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package etc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/echovault/echovault/src/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setKeyFunc(cmd []string) ([]string, error) {
|
||||||
|
if len(cmd) != 3 {
|
||||||
|
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
|
||||||
|
}
|
||||||
|
return []string{cmd[1]}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setNXKeyFunc(cmd []string) ([]string, error) {
|
||||||
|
if len(cmd) != 3 {
|
||||||
|
return nil, errors.New(utils.WRONG_ARGS_RESPONSE)
|
||||||
|
}
|
||||||
|
return []string{cmd[1]}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func msetKeyFunc(cmd []string) ([]string, error) {
|
||||||
|
if len(cmd[1:])%2 != 0 {
|
||||||
|
return nil, errors.New("each key must be paired with a value")
|
||||||
|
}
|
||||||
|
var keys []string
|
||||||
|
for i, key := range cmd[1:] {
|
||||||
|
if i%2 == 0 {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys, nil
|
||||||
|
}
|
Reference in New Issue
Block a user