mirror of
https://github.com/EchoVault/SugarDB.git
synced 2025-10-10 18:30:11 +08:00
Created outward-facing API or generic module commands
This commit is contained in:
@@ -219,3 +219,45 @@ func FilterExpiredKeys(state map[string]KeyData) map[string]KeyData {
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
func EncodeCommand(cmd []string) []byte {
|
||||
res := fmt.Sprintf("*%d\r\n", len(cmd))
|
||||
for _, token := range cmd {
|
||||
res += fmt.Sprintf("$%d\r\n%s\r\n", len(token), token)
|
||||
}
|
||||
return []byte(res)
|
||||
}
|
||||
|
||||
func ParseStringResponse(b []byte) (string, error) {
|
||||
r := resp.NewReader(bytes.NewReader(b))
|
||||
v, _, err := r.ReadValue()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return v.String(), nil
|
||||
}
|
||||
|
||||
func ParseIntegerResponse(b []byte) (int, error) {
|
||||
r := resp.NewReader(bytes.NewReader(b))
|
||||
v, _, err := r.ReadValue()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return v.Integer(), nil
|
||||
}
|
||||
|
||||
func ParseArrayResponse(b []byte) ([]string, error) {
|
||||
r := resp.NewReader(bytes.NewReader(b))
|
||||
v, _, err := r.ReadValue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if v.IsNull() {
|
||||
return []string{}, nil
|
||||
}
|
||||
arr := make([]string, len(v.Array()))
|
||||
for i, e := range v.Array() {
|
||||
arr[i] = e.String()
|
||||
}
|
||||
return arr, nil
|
||||
}
|
||||
|
@@ -13,3 +13,269 @@
|
||||
// limitations under the License.
|
||||
|
||||
package echovault
|
||||
|
||||
import (
|
||||
"github.com/echovault/echovault/internal"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type SETOptions struct {
|
||||
NX bool
|
||||
XX bool
|
||||
LT bool
|
||||
GT bool
|
||||
GET bool
|
||||
EX int
|
||||
PX int
|
||||
EXAT int
|
||||
PXAT int
|
||||
}
|
||||
|
||||
type EXPIREOptions struct {
|
||||
NX bool
|
||||
XX bool
|
||||
LT bool
|
||||
GT bool
|
||||
}
|
||||
|
||||
type PEXPIREOptions EXPIREOptions
|
||||
|
||||
type EXPIREATOptions EXPIREOptions
|
||||
|
||||
type PEXPIREATOptions EXPIREOptions
|
||||
|
||||
func (server *EchoVault) SET(key, value string, options SETOptions) (string, error) {
|
||||
cmd := []string{"SET", key, value}
|
||||
|
||||
switch {
|
||||
case options.NX:
|
||||
cmd = append(cmd, "NX")
|
||||
case options.XX:
|
||||
cmd = append(cmd, "XX")
|
||||
}
|
||||
|
||||
switch {
|
||||
case options.EX != 0:
|
||||
cmd = append(cmd, []string{"EX", strconv.Itoa(options.EX)}...)
|
||||
case options.PX != 0:
|
||||
cmd = append(cmd, []string{"PX", strconv.Itoa(options.PX)}...)
|
||||
case options.EXAT != 0:
|
||||
cmd = append(cmd, []string{"EXAT", strconv.Itoa(options.EXAT)}...)
|
||||
case options.PXAT != 0:
|
||||
cmd = append(cmd, []string{"PXAT", strconv.Itoa(options.PXAT)}...)
|
||||
}
|
||||
|
||||
if options.GET {
|
||||
cmd = append(cmd, "GET")
|
||||
}
|
||||
|
||||
encoded := internal.EncodeCommand(cmd)
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return internal.ParseStringResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) MSET(kvPairs map[string]string) (string, error) {
|
||||
cmd := []string{"MSET"}
|
||||
|
||||
for k, v := range kvPairs {
|
||||
cmd = append(cmd, []string{k, v}...)
|
||||
}
|
||||
|
||||
encoded := internal.EncodeCommand(cmd)
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return internal.ParseStringResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) GET(key string) (string, error) {
|
||||
encoded := internal.EncodeCommand([]string{"GET", key})
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return internal.ParseStringResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) MGET(keys []string) ([]string, error) {
|
||||
encoded := internal.EncodeCommand(append([]string{"MGET"}, keys...))
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
return internal.ParseArrayResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) DEL(keys []string) (int, error) {
|
||||
encoded := internal.EncodeCommand(append([]string{"DEL"}, keys...))
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) PERSIST(key string) (int, error) {
|
||||
encoded := internal.EncodeCommand([]string{"PERSIST", key})
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) EXPIRETIME(key string) (int, error) {
|
||||
encoded := internal.EncodeCommand([]string{"EXPIRETIME", key})
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) PEXPIRETIME(key string) (int, error) {
|
||||
encoded := internal.EncodeCommand([]string{"PEXPIRETIME", key})
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) TTL(key string) (int, error) {
|
||||
encoded := internal.EncodeCommand([]string{"TTL", key})
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) PTTL(key string) (int, error) {
|
||||
encoded := internal.EncodeCommand([]string{"PTTL", key})
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) EXPIRE(key string, seconds int, options EXPIREOptions) (int, error) {
|
||||
cmd := []string{"EXPIRE", key, strconv.Itoa(seconds)}
|
||||
|
||||
switch {
|
||||
case options.NX:
|
||||
cmd = append(cmd, "NX")
|
||||
case options.XX:
|
||||
cmd = append(cmd, "XX")
|
||||
case options.LT:
|
||||
cmd = append(cmd, "LT")
|
||||
case options.GT:
|
||||
cmd = append(cmd, "GT")
|
||||
}
|
||||
|
||||
encoded := internal.EncodeCommand(cmd)
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) PEXPIRE(key string, milliseconds int, options PEXPIREOptions) (int, error) {
|
||||
cmd := []string{"PEXPIRE", key, strconv.Itoa(milliseconds)}
|
||||
|
||||
switch {
|
||||
case options.NX:
|
||||
cmd = append(cmd, "NX")
|
||||
case options.XX:
|
||||
cmd = append(cmd, "XX")
|
||||
case options.LT:
|
||||
cmd = append(cmd, "LT")
|
||||
case options.GT:
|
||||
cmd = append(cmd, "GT")
|
||||
}
|
||||
|
||||
encoded := internal.EncodeCommand(cmd)
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) EXPIREAT(key string, unixSeconds int, options EXPIREATOptions) (int, error) {
|
||||
cmd := []string{"EXPIREAT", key, strconv.Itoa(unixSeconds)}
|
||||
|
||||
switch {
|
||||
case options.NX:
|
||||
cmd = append(cmd, "NX")
|
||||
case options.XX:
|
||||
cmd = append(cmd, "XX")
|
||||
case options.LT:
|
||||
cmd = append(cmd, "LT")
|
||||
case options.GT:
|
||||
cmd = append(cmd, "GT")
|
||||
}
|
||||
|
||||
encoded := internal.EncodeCommand(cmd)
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
||||
func (server *EchoVault) PEXPIREAT(key string, unixMilliseconds int, options PEXPIREATOptions) (int, error) {
|
||||
cmd := []string{"PEXPIREAT", key, strconv.Itoa(unixMilliseconds)}
|
||||
|
||||
switch {
|
||||
case options.NX:
|
||||
cmd = append(cmd, "NX")
|
||||
case options.XX:
|
||||
cmd = append(cmd, "XX")
|
||||
case options.LT:
|
||||
cmd = append(cmd, "LT")
|
||||
case options.GT:
|
||||
cmd = append(cmd, "GT")
|
||||
}
|
||||
|
||||
encoded := internal.EncodeCommand(cmd)
|
||||
|
||||
b, err := server.handleCommand(server.context, encoded, nil, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return internal.ParseIntegerResponse(b)
|
||||
}
|
||||
|
@@ -524,7 +524,7 @@ PXAT - Expire at the exat time in unix milliseconds (positive integer).`,
|
||||
{
|
||||
Command: "mget",
|
||||
Categories: []string{utils.ReadCategory, utils.FastCategory},
|
||||
Description: "(MGET key1 [key2]) Get multiple values from the specified keys.",
|
||||
Description: "(MGET key [key ...]) Get multiple values from the specified keys.",
|
||||
Sync: false,
|
||||
KeyExtractionFunc: mgetKeyFunc,
|
||||
HandlerFunc: handleMGet,
|
||||
|
Reference in New Issue
Block a user