mirror of
https://github.com/EchoVault/SugarDB.git
synced 2025-10-09 18:00:23 +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
|
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.
|
// limitations under the License.
|
||||||
|
|
||||||
package echovault
|
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",
|
Command: "mget",
|
||||||
Categories: []string{utils.ReadCategory, utils.FastCategory},
|
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,
|
Sync: false,
|
||||||
KeyExtractionFunc: mgetKeyFunc,
|
KeyExtractionFunc: mgetKeyFunc,
|
||||||
HandlerFunc: handleMGet,
|
HandlerFunc: handleMGet,
|
||||||
|
Reference in New Issue
Block a user