Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go:Implement GetEx command #2329

Merged
merged 5 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
janhavigupta007 marked this conversation as resolved.
Show resolved Hide resolved
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
Loading