Skip to content

Commit

Permalink
Sort,Sort_RO,Sort Store commands
Browse files Browse the repository at this point in the history
Signed-off-by: Niharika Bhavaraju <[email protected]>
  • Loading branch information
niharikabhavaraju committed Dec 29, 2024
1 parent 4df3757 commit 2d122ef
Show file tree
Hide file tree
Showing 5 changed files with 805 additions and 0 deletions.
51 changes: 51 additions & 0 deletions go/api/base_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1405,3 +1405,54 @@ func (client *baseClient) ZPopMaxWithCount(key string, count int64) (map[Result[
}
return handleStringDoubleMapResponse(result)
}

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

func (client *baseClient) SortWithOptions(key string, options *SortOptions) ([]Result[string], error) {
optionArgs := options.ToArgs()
result, err := client.executeCommand(C.Sort, append([]string{key}, optionArgs...))
if err != nil {
return nil, err
}
return handleStringArrayResponse(result)
}

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

func (client *baseClient) SortReadOnlyWithOptions(key string, options *SortOptions) ([]Result[string], error) {
optionArgs := options.ToArgs()
result, err := client.executeCommand(C.SortReadOnly, append([]string{key}, optionArgs...))
if err != nil {
return nil, err
}
return handleStringArrayResponse(result)
}

func (client *baseClient) SortStore(key string, destination string) (Result[int64], error) {
result, err := client.executeCommand(C.Sort, []string{key, "STORE", destination})
if err != nil {
return CreateNilInt64Result(), err
}
return handleLongResponse(result)
}

func (client *baseClient) SortStoreWithOptions(key string, destination string, options *SortOptions) (Result[int64], error) {
optionArgs := options.ToArgs()
result, err := client.executeCommand(C.Sort, append([]string{key, "STORE", destination}, optionArgs...))
if err != nil {
return CreateNilInt64Result(), err
}
return handleLongResponse(result)
}
123 changes: 123 additions & 0 deletions go/api/command_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package api

import (
"fmt"
"strconv"

"github.com/valkey-io/valkey-glide/go/glide/utils"
Expand Down Expand Up @@ -279,6 +280,128 @@ func (listDirection ListDirection) toString() (string, error) {
}
}

const (
// LIMIT subcommand string to include in the SORT and SORT_RO commands.
LIMIT_COMMAND_STRING = "LIMIT"
// ALPHA subcommand string to include in the SORT and SORT_RO commands.
ALPHA_COMMAND_STRING = "ALPHA"
// BY subcommand string to include in the SORT and SORT_RO commands.
// Supported in cluster mode since Valkey version 8.0 and above.
BY_COMMAND_STRING = "BY"
// GET subcommand string to include in the SORT and SORT_RO commands.
GET_COMMAND_STRING = "GET"
)

// Limit struct represents the range of elements to retrieve
// The LIMIT argument is commonly used to specify a subset of results from the matching elements, similar to the
// LIMIT clause in SQL (e.g., `SELECT LIMIT offset, count`).
type Limit struct {
// The starting position of the range, zero based.
Offset int64
// The maximum number of elements to include in the range. A negative count returns all elementsnfrom the offset.
Count int64
}

// OrderBy specifies the order to sort the elements. Can be ASC (ascending) or DESC(descending).
type OrderBy string

const (
ASC OrderBy = "ASC"
DESC OrderBy = "DESC"
)

// SortOptions struct combines both the base options and additional sorting options
type SortOptions struct {
// Limit Limits the range of elements
Limit *Limit

// OrderBy sets the order to sort by (ASC or DESC)
OrderBy OrderBy

// IsAlpha determines whether to sort lexicographically (true) or numerically (false)
IsAlpha bool

// ByPattern - a pattern to sort by external keys instead of by the elements stored at the key themselves. The
// pattern should contain an asterisk (*) as a placeholder for the element values, where the value
// from the key replaces the asterisk to create the key name. For example, if key
// contains IDs of objects, byPattern can be used to sort these IDs based on an
// attribute of the objects, like their weights or timestamps. Supported in cluster mode since
// Valkey version 8.0 and above.
ByPattern string

// A pattern used to retrieve external keys' values, instead of the elements at key.
// The pattern should contain an asterisk (*) as a placeholder for the element values, where the
// value from key replaces the asterisk to create the key name. This
// allows the sorted elements to be transformed based on the related keys values. For example, if
// key< contains IDs of users, getPatterns can be used to retrieve
// specific attributes of these users, such as their names or email addresses. E.g., if
// getPatterns is name_*, the command will return the values of the keys
// name_&lt;element&gt; for each sorted element. Multiple getPatterns
// arguments can be provided to retrieve multiple attributes. The special value # can
// be used to include the actual element from key being sorted. If not provided, only
// the sorted elements themselves are returned.
// Supported in cluster mode since Valkey version 8.0 and above.
GetPatterns []string // List of patterns to retrieve external keys' values
}

func NewSortOptions() *SortOptions {
return &SortOptions{
OrderBy: ASC, // Default order is ascending
IsAlpha: false, // Default is numeric sorting
}
}

func (opts *SortOptions) SetLimit(offset, count int64) *SortOptions {
opts.Limit = &Limit{Offset: offset, Count: count}
return opts
}

func (opts *SortOptions) SetOrderBy(order OrderBy) *SortOptions {
opts.OrderBy = order
return opts
}

func (opts *SortOptions) SetIsAlpha(isAlpha bool) *SortOptions {
opts.IsAlpha = isAlpha
return opts
}

func (opts *SortOptions) SetByPattern(byPattern string) *SortOptions {
opts.ByPattern = byPattern
return opts
}

func (opts *SortOptions) AddGetPattern(getPattern string) *SortOptions {
opts.GetPatterns = append(opts.GetPatterns, getPattern)
return opts
}

// ToArgs creates the arguments to be used in SORT and SORT_RO commands.
func (opts *SortOptions) ToArgs() []string {
var args []string

if opts.Limit != nil {
args = append(args, LIMIT_COMMAND_STRING, fmt.Sprintf("%d", opts.Limit.Offset), fmt.Sprintf("%d", opts.Limit.Count))
}

if opts.OrderBy != "" {
args = append(args, string(opts.OrderBy))
}

if opts.IsAlpha {
args = append(args, ALPHA_COMMAND_STRING)
}

if opts.ByPattern != "" {
args = append(args, BY_COMMAND_STRING, opts.ByPattern)
}

for _, getPattern := range opts.GetPatterns {
args = append(args, GET_COMMAND_STRING, getPattern)
}
return args
}

// This base option struct represents the common set of optional arguments for the SCAN family of commands.
// Concrete implementations of this class are tied to specific SCAN commands (`SCAN`, `SSCAN`).
type BaseScanOptions struct {
Expand Down
172 changes: 172 additions & 0 deletions go/api/generic_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,178 @@ type GenericBaseCommands interface {
// [valkey.io]: https://valkey.io/commands/pttl/
PTTL(key string) (Result[int64], error)

// Sorts the elements in the list, set, or sorted set at key and returns the result.
// The sort command can be used to sort elements based on different criteria and apply
// transformations on sorted elements.
// To store the result into a new key, see {@link #sortStore(string, string)}.
//
// Parameters:
// key - The key of the list, set, or sorted set to be sorted.
//
// Return value:
// An Array of sorted elements.
//
// Example:
//
// result, err := client.Sort("key")
// result.Value(): [{1 false} {2 false} {3 false}]
// result.IsNil(): false
//
// [valkey.io]: https://valkey.io/commands/sort/
Sort(key string) ([]Result[string], error)

// Sorts the elements in the list, set, or sorted set at key and returns the result.
// The sort command can be used to sort elements based on different criteria and apply
// transformations on sorted elements.
// To store the result into a new key, see {@link #sortStore(string, string)}.
//
// Note:
// In cluster mode, if keys in `keyValueMap` map to different hash slots, the command
// will be split across these slots and executed separately for each. This means the command
// is atomic only at the slot level. If one or more slot-specific requests fail, the entire
// call will return the first encountered error, even though some requests may have succeeded
// while others did not. If this behavior impacts your application logic, consider splitting
// the request into sub-requests per slot to ensure atomicity.
// The use of {@link SortOptions#byPattern} and {@link SortOptions#getPatterns} in cluster mode is
// supported since Valkey version 8.0.
//
// Parameters:
// key - The key of the list, set, or sorted set to be sorted.
// sortOptions- The {@link SortOptions}.
//
// Return value:
// An Array of sorted elements.
//
// Example:
//
// options := api.NewSortOptions().SetByPattern("weight_*").SetIsAlpha(false).AddGetPattern("object_*").AddGetPattern("#")
// result, err := client.Sort("key", options)
// result.Value(): [{Object_3 false} {c false} {Object_1 false} {a false} {Object_2 false} {b false}]
// result.IsNil(): false
//
// [valkey.io]: https://valkey.io/commands/sort/
SortWithOptions(key string, sortOptions *SortOptions) ([]Result[string], error)

// Sorts the elements in the list, set, or sorted set at key and stores the result in
// destination. The sort command can be used to sort elements based on
// different criteria, apply transformations on sorted elements, and store the result in a new key.
// The sort command can be used to sort elements based on different criteria and apply
// transformations on sorted elements.
// To get the sort result without storing it into a key, see {@link #sort(String)} or {@link #sortReadOnly(String)}.
//
// Note:
// In cluster mode, if keys in `keyValueMap` map to different hash slots, the command
// will be split across these slots and executed separately for each. This means the command
// is atomic only at the slot level. If one or more slot-specific requests fail, the entire
// call will return the first encountered error, even though some requests may have succeeded
// while others did not. If this behavior impacts your application logic, consider splitting
// the request into sub-requests per slot to ensure atomicity.
//
// Parameters:
// key - The key of the list, set, or sorted set to be sorted.
// destination - The key where the sorted result will be stored.
//
// Return value:
// The number of elements in the sorted key stored at destination.
//
// Example:
//
// result, err := client.SortStore("key","destkey")
// result.Value(): 1
// result.IsNil(): false
//
// [valkey.io]: https://valkey.io/commands/sort/
SortStore(key string, destination string) (Result[int64], error)

// Sorts the elements in the list, set, or sorted set at key and stores the result in
// destination. The sort command can be used to sort elements based on
// different criteria, apply transformations on sorted elements, and store the result in a new key.
// The sort command can be used to sort elements based on different criteria and apply
// transformations on sorted elements.
// To get the sort result without storing it into a key, see {@link #sort(String)} or {@link #sortReadOnly(String)}.
//
// Note:
// In cluster mode, if keys in `keyValueMap` map to different hash slots, the command
// will be split across these slots and executed separately for each. This means the command
// is atomic only at the slot level. If one or more slot-specific requests fail, the entire
// call will return the first encountered error, even though some requests may have succeeded
// while others did not. If this behavior impacts your application logic, consider splitting
// the request into sub-requests per slot to ensure atomicity.
// The use of {@link SortOptions#byPattern} and {@link SortOptions#getPatterns}
// in cluster mode is supported since Valkey version 8.0.
//
// Parameters:
// key - The key of the list, set, or sorted set to be sorted.
// destination - The key where the sorted result will be stored.
// sortOptions- The {@link SortOptions}.
//
// Return value:
// The number of elements in the sorted key stored at destination.
//
// Example:
//
// options := api.NewSortOptions().SetByPattern("weight_*").SetIsAlpha(false).AddGetPattern("object_*").AddGetPattern("#")
// result, err := client.SortStore("key","destkey",options)
// result.Value(): 1
// result.IsNil(): false
//
// [valkey.io]: https://valkey.io/commands/sort/
SortStoreWithOptions(key string, destination string, sortOptions *SortOptions) (Result[int64], error)

// Sorts the elements in the list, set, or sorted set at key and returns the result.
// The sortReadOnly command can be used to sort elements based on different criteria and apply
// transformations on sorted elements.
// This command is routed depending on the client's {@link ReadFrom} strategy.
//
// Parameters:
// key - The key of the list, set, or sorted set to be sorted.
//
// Return value:
// An Array of sorted elements.
//
// Example:
//
// result, err := client.SortReadOnly("key")
// result.Value(): [{1 false} {2 false} {3 false}]
// result.IsNil(): false
//
// [valkey.io]: https://valkey.io/commands/sort/
SortReadOnly(key string) ([]Result[string], error)

// Sorts the elements in the list, set, or sorted set at key and returns the result.
// The sort command can be used to sort elements based on different criteria and apply
// transformations on sorted elements.
// This command is routed depending on the client's {@link ReadFrom} strategy.
//
// Note:
// In cluster mode, if keys in `keyValueMap` map to different hash slots, the command
// will be split across these slots and executed separately for each. This means the command
// is atomic only at the slot level. If one or more slot-specific requests fail, the entire
// call will return the first encountered error, even though some requests may have succeeded
// while others did not. If this behavior impacts your application logic, consider splitting
// the request into sub-requests per slot to ensure atomicity.
// The use of {@link SortOptions#byPattern} and {@link SortOptions#getPatterns} in cluster mode is
// supported since Valkey version 8.0.
// The use of {@link SortOptions#byPattern} and {@link SortOptions#getPatterns} in cluster mode is
// supported since Valkey version 8.0.
//
// Parameters:
// key - The key of the list, set, or sorted set to be sorted.
// sortOptions- The {@link SortOptions}.
//
// Return value:
// An Array of sorted elements.
//
// Example:
//
// options := api.NewSortOptions().SetByPattern("weight_*").SetIsAlpha(false).AddGetPattern("object_*").AddGetPattern("#")
// result, err := client.SortReadOnly("key", options)
// result.Value(): [{Object_3 false} {c false} {Object_1 false} {a false} {Object_2 false} {b false}]
// result.IsNil(): false
//
// [valkey.io]: https://valkey.io/commands/sort/
SortReadOnlyWithOptions(key string, sortOptions *SortOptions) ([]Result[string], error)

// Unlink (delete) multiple keys from the database. A key is ignored if it does not exist.
// This command, similar to Del However, this command does not block the server
//
Expand Down
Loading

0 comments on commit 2d122ef

Please sign in to comment.