Skip to content

Commit

Permalink
Go:Implementing List commands
Browse files Browse the repository at this point in the history
Signed-off-by: Janhavi Gupta <[email protected]>
  • Loading branch information
janhavigupta007 committed Oct 3, 2024
1 parent 02a5122 commit 7788a8a
Show file tree
Hide file tree
Showing 4 changed files with 402 additions and 36 deletions.
77 changes: 77 additions & 0 deletions go/api/base_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,3 +512,80 @@ func (client *baseClient) RPush(key string, elements []string) (Result[int64], e

return handleLongResponse(result)
}

func (client *baseClient) LRange(key string, start int64, end int64) ([]Result[string], error) {
result, err := client.executeCommand(C.LRange, []string{key, utils.IntToString(start), utils.IntToString(end)})
if err != nil {
return nil, err
}

return handleStringArrayResponse(result)
}

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

return handleStringOrNullResponse(result)
}

func (client *baseClient) LTrim(key string, start int64, end int64) (Result[string], error) {
result, err := client.executeCommand(C.LTrim, []string{key, utils.IntToString(start), utils.IntToString(end)})
if err != nil {
return CreateNilStringResult(), err
}

return handleStringResponse(result)
}

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

return handleLongResponse(result)
}

func (client *baseClient) LRem(key string, count int64, element string) (Result[int64], error) {
result, err := client.executeCommand(C.LRem, []string{key, utils.IntToString(count), element})
if err != nil {
return CreateNilInt64Result(), err
}

return handleLongResponse(result)
}

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

return handleStringOrNullResponse(result)
}

func (client *baseClient) RPopCount(key string, count int64) ([]Result[string], error) {
result, err := client.executeCommand(C.RPop, []string{key, utils.IntToString(count)})
if err != nil {
return nil, err
}

return handleStringArrayOrNullResponse(result)
}

func (client *baseClient) LInsert(key string, options *LInsertOptions, pivot string, element string) (Result[int64], error) {
optionArgs, err := options.toArgs()
if err != nil {
return CreateNilInt64Result(), err
}

result, err := client.executeCommand(C.LInsert, []string{key, optionArgs, pivot, element})
if err != nil {
return CreateNilInt64Result(), err
}

return handleLongResponse(result)
}
55 changes: 31 additions & 24 deletions go/api/command_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,38 +204,45 @@ const (
MaxLenKeyword string = "MAXLEN" // Valkey API keyword used to determine the maximum number of list items to compare.
)

// LPosOptions represents optional arguments for the [api.ListCommands.LPosWithOptions] and
// [api.ListCommands.LPosCountWithOptions] commands.
// LInsertOptions represents arguments for the [api.ListCommands.LInsert].
//
// See [valkey.io]
//
// [valkey.io]: https://valkey.io/commands/lpos/
type LPosOptions struct {
// Represents if the rank option is set.
IsRankSet bool
// The rank of the match to return.
Rank int64
// Represents if the max length parameter is set.
IsMaxLenSet bool
// The maximum number of comparisons to make between the element and the items in the list.
MaxLen int64
// [valkey.io]: https://valkey.io/commands/linsert/
type LInsertOptions struct {
// Defines where to insert new elements into a list.
InsertPosition InsertPosition
}

func (opts *LPosOptions) toArgs() []string {
args := []string{}
if opts.IsRankSet {
args = append(args, RankKeyword, utils.IntToString(opts.Rank))
}
func NewLInsertOptionsBuilder() *LInsertOptions {
return &LInsertOptions{}
}

if opts.IsMaxLenSet {
args = append(args, MaxLenKeyword, utils.IntToString(opts.MaxLen))
}
func (linsertOptions *LInsertOptions) SetPosition(position InsertPosition) *LInsertOptions {
linsertOptions.InsertPosition = position
return linsertOptions
}

return args
func (opts *LInsertOptions) toArgs() (string, error) {
if opts == nil {
return "", &RequestError{"Position not provided"}
}
switch opts.InsertPosition {
case Before:
return string(Before), nil
case After:
return string(After), nil
default:
return "", &RequestError{"Invalid position"}
}
}

// A ConditionalSet defines where to insert new elements into a list.
type InsertPosition string

const (
CountKeyword string = "COUNT" // Valkey API keyword used to extract specific number of matching indices from a list.
RankKeyword string = "RANK" // Valkey API keyword use to determine the rank of the match to return.
MaxLenKeyword string = "MAXLEN" // Valkey API keyword used to determine the maximum number of list items to compare.
// Insert new element before the pivot.
Before InsertPosition = "BEFORE"
// Insert new element after the pivot.
After InsertPosition = "AFTER"
)
30 changes: 19 additions & 11 deletions go/api/list_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@ type ListCommands interface {
RPush(key string, elements []string) (Result[int64], error)

// Returns the specified elements of the list stored at key.
// The offsets start and end are zero-based indexes, with 0 being the first element of the list, 1 being the next element and so on. These offsets can also be negative numbers indicating offsets starting at the end of the list, with -1 being the last element of the list, <code>-2</code> being the penultimate, and so on.
// The offsets start and end are zero-based indexes, with 0 being the first element of the list, 1 being the next element
// and so on. These offsets can also be negative numbers indicating offsets starting at the end of the list, with -1 being
// the last element of the list, -2 being the penultimate, and so on.
//
// See [valkey.io] for details.
//
Expand All @@ -211,7 +213,8 @@ type ListCommands interface {
//
// For example:
// 1. result, err := client.LRange("my_list", 0, 2)
// result: []api.Result[string]{api.CreateStringResult("value1"), api.CreateStringResult("value2"), api.CreateStringResult("value3")}
// result: []api.Result[string]{api.CreateStringResult("value1"), api.CreateStringResult("value2"),
// api.CreateStringResult("value3")}
// 2. result, err := client.LRange("my_list", -2, -1)
// result: []api.Result[string]{api.CreateStringResult("value2"), api.CreateStringResult("value3")}
// 3. result, err := client.LRange("non_existent_key", 0, 2)
Expand All @@ -221,7 +224,9 @@ type ListCommands interface {
LRange(key string, start int64, end int64) ([]Result[string], error)

// Returns the element at index from the list stored at key.
// The index is zero-based, so 0 means the first element, 1 the second element and so on. Negative indices can be used to designate elements starting at the tail of the list. Here, -1 means the last element, -2 means the penultimate and so forth.
// The index is zero-based, so 0 means the first element, 1 the second element and so on. Negative indices can be used to
// designate elements starting at the tail of the list. Here, -1 means the last element, -2 means the penultimate and so
// forth.
//
// See [valkey.io] for details.
//
Expand All @@ -245,8 +250,9 @@ type ListCommands interface {
LIndex(key string, index int64) (Result[string], error)

// Trims an existing list so that it will contain only the specified range of elements specified.
// The offsets start and end are zero-based indexes, with 0 being the first element of the list, 1 being the next element and so on.
// These offsets can also be negative numbers indicating offsets starting at the end of the list, with -1 being the last element of the list, -2 being the penultimate, and so on.
// The offsets start and end are zero-based indexes, with 0 being the first element of the list, 1 being the next element
// and so on. These offsets can also be negative numbers indicating offsets starting at the end of the list, with -1 being
// the last element of the list, -2 being the penultimate, and so on.
//
// See [valkey.io] for details.
//
Expand All @@ -257,7 +263,8 @@ type ListCommands interface {
//
// Return value:
// The Result[string] containing always "OK".
// If start exceeds the end of the list, or if start is greater than end, the result will be an empty list (which causes key to be removed).
// If start exceeds the end of the list, or if start is greater than end, the result will be an empty list (which causes
// key to be removed).
// If end exceeds the actual end of the list, it will be treated like the last element of the list.
// If key does not exist, OK will be returned without changes to the database.
//
Expand Down Expand Up @@ -291,7 +298,8 @@ type ListCommands interface {
// Removes the first count occurrences of elements equal to element from the list stored at key.
// If count is positive: Removes elements equal to element moving from head to tail.
// If count is negative: Removes elements equal to element moving from tail to head.
// If count is 0 or count is greater than the occurrences of elements equal to element, it removes all elements equal to element.
// If count is 0 or count is greater than the occurrences of elements equal to element, it removes all elements equal to
// element.
//
// See [valkey.io] for details.
//
Expand Down Expand Up @@ -362,7 +370,7 @@ type ListCommands interface {
//
// Parameters:
// key - The key of the list.
// position - The relative position to insert into - either {@link InsertPosition#BEFORE} or {@link InsertPosition#AFTER} the pivot.
// options - The relative position to insert into - either InsertPosition.Before or InsertPosition.After the pivot.
// pivot - An element of the list.
// element - The new element to insert.
//
Expand All @@ -372,9 +380,9 @@ type ListCommands interface {
// If the pivot wasn't found, returns 0.
//
// For example:
// result, err := client.LInsert("my_list", BEFORE, "World", "There")
// result, err := client.LInsert("my_list", api.NewLInsertOptionsBuilder().SetPosition(api.Before), "World", "There")
// result.Value() > 0L;
//
// [valkey.io]: https://valkey.io/commands/rpop/
LInsert(key string, position *InsertPosition, pivot string, element string) (Result[int64], error)
// [valkey.io]: https://valkey.io/commands/linsert/
LInsert(key string, options *LInsertOptions, pivot string, element string) (Result[int64], error)
}
Loading

0 comments on commit 7788a8a

Please sign in to comment.