Skip to content

Commit

Permalink
Go:Implement GetEx command (valkey-io#2329)
Browse files Browse the repository at this point in the history
* Go:Implement GetEx command

Signed-off-by: Janhavi Gupta <[email protected]>
  • Loading branch information
janhavigupta007 authored Oct 1, 2024
1 parent 22a2cee commit 4b53749
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 24 deletions.
30 changes: 29 additions & 1 deletion go/api/base_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,12 @@ func (client *baseClient) Set(key string, value string) (Result[string], error)
}

func (client *baseClient) SetWithOptions(key string, value string, options *SetOptions) (Result[string], error) {
result, err := client.executeCommand(C.Set, append([]string{key, value}, options.toArgs()...))
optionArgs, err := options.toArgs()
if err != nil {
return CreateNilStringResult(), err
}

result, err := client.executeCommand(C.Set, append([]string{key, value}, optionArgs...))
if err != nil {
return CreateNilStringResult(), err
}
Expand All @@ -169,6 +174,29 @@ func (client *baseClient) Get(key string) (Result[string], error) {
return handleStringOrNullResponse(result)
}

func (client *baseClient) GetEx(key string) (Result[string], error) {
result, err := client.executeCommand(C.GetEx, []string{key})
if err != nil {
return CreateNilStringResult(), err
}

return handleStringOrNullResponse(result)
}

func (client *baseClient) GetExWithOptions(key string, options *GetExOptions) (Result[string], error) {
optionArgs, err := options.toArgs()
if err != nil {
return CreateNilStringResult(), err
}

result, err := client.executeCommand(C.GetEx, append([]string{key}, optionArgs...))
if err != nil {
return CreateNilStringResult(), err
}

return handleStringOrNullResponse(result)
}

func (client *baseClient) MSet(keyValueMap map[string]string) (Result[string], error) {
result, err := client.executeCommand(C.MSet, utils.MapToString(keyValueMap))
if err != nil {
Expand Down
88 changes: 83 additions & 5 deletions go/api/command_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,32 @@ type SetOptions struct {
// Equivalent to GET in the valkey API.
ReturnOldValue bool
// If not set, no expiry time will be set for the value.
// Supported ExpiryTypes ("EX", "PX", "EXAT", "PXAT", "KEEPTTL")
Expiry *Expiry
}

func (opts *SetOptions) toArgs() []string {
func NewSetOptionsBuilder() *SetOptions {
return &SetOptions{}
}

func (setOptions *SetOptions) SetConditionalSet(conditionalSet ConditionalSet) *SetOptions {
setOptions.ConditionalSet = conditionalSet
return setOptions
}

func (setOptions *SetOptions) SetReturnOldValue(returnOldValue bool) *SetOptions {
setOptions.ReturnOldValue = returnOldValue
return setOptions
}

func (setOptions *SetOptions) SetExpiry(expiry *Expiry) *SetOptions {
setOptions.Expiry = expiry
return setOptions
}

func (opts *SetOptions) toArgs() ([]string, error) {
args := []string{}
var err error
if opts.ConditionalSet != "" {
args = append(args, string(opts.ConditionalSet))
}
Expand All @@ -32,13 +53,55 @@ func (opts *SetOptions) toArgs() []string {
}

if opts.Expiry != nil {
args = append(args, string(opts.Expiry.Type))
if opts.Expiry.Type != KeepExisting {
args = append(args, strconv.FormatUint(opts.Expiry.Count, 10))
switch opts.Expiry.Type {
case Seconds, Milliseconds, UnixSeconds, UnixMilliseconds:
args = append(args, string(opts.Expiry.Type), strconv.FormatUint(opts.Expiry.Count, 10))
case KeepExisting:
args = append(args, string(opts.Expiry.Type))
default:
err = &RequestError{"Invalid expiry type"}
}
}

return args
return args, err
}

// GetExOptions represents optional arguments for the [api.StringCommands.GetExWithOptions] command.
//
// See [valkey.io]
//
// [valkey.io]: https://valkey.io/commands/getex/
type GetExOptions struct {
// If not set, no expiry time will be set for the value.
// Supported ExpiryTypes ("EX", "PX", "EXAT", "PXAT", "PERSIST")
Expiry *Expiry
}

func NewGetExOptionsBuilder() *GetExOptions {
return &GetExOptions{}
}

func (getExOptions *GetExOptions) SetExpiry(expiry *Expiry) *GetExOptions {
getExOptions.Expiry = expiry
return getExOptions
}

func (opts *GetExOptions) toArgs() ([]string, error) {
args := []string{}
var err error

if opts.Expiry != nil {
switch opts.Expiry.Type {
case Seconds, Milliseconds, UnixSeconds, UnixMilliseconds:
args = append(args, string(opts.Expiry.Type), strconv.FormatUint(opts.Expiry.Count, 10))
case Persist:
args = append(args, string(opts.Expiry.Type))
default:
err = &RequestError{"Invalid expiry type"}
}
}

return args, err
}

const returnOldValue = "GET"
Expand All @@ -59,6 +122,20 @@ type Expiry struct {
Count uint64
}

func NewExpiryBuilder() *Expiry {
return &Expiry{}
}

func (ex *Expiry) SetType(expiryType ExpiryType) *Expiry {
ex.Type = expiryType
return ex
}

func (ex *Expiry) SetCount(count uint64) *Expiry {
ex.Count = count
return ex
}

// An ExpiryType is used to configure the type of expiration for a value.
type ExpiryType string

Expand All @@ -68,4 +145,5 @@ const (
Milliseconds ExpiryType = "PX" // expire the value after [api.Expiry.Count] milliseconds
UnixSeconds ExpiryType = "EXAT" // expire the value after the Unix time specified by [api.Expiry.Count], in seconds
UnixMilliseconds ExpiryType = "PXAT" // expire the value after the Unix time specified by [api.Expiry.Count], in milliseconds
Persist ExpiryType = "PERSIST" // Remove the expiry associated with the key
)
61 changes: 53 additions & 8 deletions go/api/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type StringCommands interface {
// Parameters:
// key - The key to store.
// value - The value to store with the given key.
// options - The Set options.
// options - The [api.SetOptions].
//
// Return value:
// If the value is successfully set, return api.Result[string] containing "OK".
Expand All @@ -48,13 +48,11 @@ type StringCommands interface {
//
// For example:
// key: initialValue
// result, err := client.SetWithOptions("key", "value", &api.SetOptions{
// ConditionalSet: api.OnlyIfExists,
// Expiry: &api.Expiry{
// Type: api.Seconds,
// Count: uint64(5),
// },
// })
// result, err := client.SetWithOptions("key", "value", api.NewSetOptionsBuilder()
// .SetExpiry(api.NewExpiryBuilder()
// .SetType(api.Seconds)
// .SetCount(uint64(5)
// ))
// result.Value(): "OK"
// result.IsNil(): false
//
Expand Down Expand Up @@ -84,6 +82,53 @@ type StringCommands interface {
// [valkey.io]: https://valkey.io/commands/get/
Get(key string) (Result[string], error)

// Get string value associated with the given key, or an empty string is returned [api.CreateNilStringResult()] if no such
// value exists.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key to be retrieved from the database.
//
// Return value:
// If key exists, returns the value of key as a Result[string]. Otherwise, return [api.CreateNilStringResult()].
//
// For example:
// 1. key: value
// result, err := client.GetEx("key")
// result.Value(): "value"
// result.IsNil(): false
// 2. result, err := client.GetEx("nonExistentKey")
// result.Value(): ""
// result.IsNil(): true
//
// [valkey.io]: https://valkey.io/commands/getex/
GetEx(key string) (Result[string], error)

// Get string value associated with the given key and optionally sets the expiration of the key.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key to be retrieved from the database.
// options - The [api.GetExOptions].
//
// Return value:
// If key exists, returns the value of key as a Result[string]. Otherwise, return [api.CreateNilStringResult()].
//
// For example:
// key: initialValue
// result, err := client.GetExWithOptions("key", api.NewGetExOptionsBuilder()
// .SetExpiry(api.NewExpiryBuilder()
// .SetType(api.Seconds)
// .SetCount(uint64(5)
// ))
// result.Value(): "initialValue"
// result.IsNil(): false
//
// [valkey.io]: https://valkey.io/commands/getex/
GetExWithOptions(key string, options *GetExOptions) (Result[string], error)

// Sets multiple keys to multiple values in a single operation.
//
// Note:
Expand Down
Loading

0 comments on commit 4b53749

Please sign in to comment.