Skip to content

Commit

Permalink
Go: Implement Set commands (valkey-io#2373)
Browse files Browse the repository at this point in the history
Go: Implement Set commands

Add SetCommands interface with methods:
SAdd, SRem, SMembers, SCard, SIsMember, SDiff, SDiffStore,
SInter, SInterCard, SInterCardLimit, SRandMember, SPop

- Include method documentation and usage examples
- Add unit tests for all new methods

Signed-off-by: umit <[email protected]>
  • Loading branch information
umit authored Oct 14, 2024
1 parent 936b70a commit b0d39ed
Show file tree
Hide file tree
Showing 6 changed files with 887 additions and 0 deletions.
112 changes: 112 additions & 0 deletions go/api/base_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import "C"

import (
"errors"
"slices"
"strconv"
"unsafe"

Expand All @@ -24,6 +25,7 @@ type BaseClient interface {
StringCommands
HashCommands
ListCommands
SetCommands
ConnectionManagementCommands
// Close terminates the client by closing all associated resources.
Close()
Expand Down Expand Up @@ -513,6 +515,116 @@ func (client *baseClient) RPush(key string, elements []string) (Result[int64], e
return handleLongResponse(result)
}

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

return handleLongResponse(result)
}

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

return handleLongResponse(result)
}

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

return handleStringSetResponse(result)
}

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

return handleLongResponse(result)
}

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

return handleBooleanResponse(result)
}

func (client *baseClient) SDiff(keys []string) (map[Result[string]]struct{}, error) {
result, err := client.executeCommand(C.SDiff, keys)
if err != nil {
return nil, err
}

return handleStringSetResponse(result)
}

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

return handleLongResponse(result)
}

func (client *baseClient) SInter(keys []string) (map[Result[string]]struct{}, error) {
result, err := client.executeCommand(C.SInter, keys)
if err != nil {
return nil, err
}

return handleStringSetResponse(result)
}

func (client *baseClient) SInterCard(keys []string) (Result[int64], error) {
result, err := client.executeCommand(C.SInterCard, append([]string{strconv.Itoa(len(keys))}, keys...))
if err != nil {
return CreateNilInt64Result(), err
}

return handleLongResponse(result)
}

func (client *baseClient) SInterCardLimit(keys []string, limit int64) (Result[int64], error) {
args := slices.Concat([]string{utils.IntToString(int64(len(keys)))}, keys, []string{"LIMIT", utils.IntToString(limit)})

result, err := client.executeCommand(C.SInterCard, args)
if err != nil {
return CreateNilInt64Result(), err
}

return handleLongResponse(result)
}

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

return handleStringResponse(result)
}

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

return handleStringResponse(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 {
Expand Down
20 changes: 20 additions & 0 deletions go/api/response_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,23 @@ func handleStringToStringMapResponse(response *C.struct_CommandResponse) (map[Re

return m, nil
}

func handleStringSetResponse(response *C.struct_CommandResponse) (map[Result[string]]struct{}, error) {
defer C.free_command_response(response)

typeErr := checkResponseType(response, C.Sets, false)
if typeErr != nil {
return nil, typeErr
}

slice := make(map[Result[string]]struct{}, response.sets_value_len)
for _, v := range unsafe.Slice(response.sets_value, response.sets_value_len) {
res, err := convertCharArrayToString(&v, true)
if err != nil {
return nil, err
}
slice[res] = struct{}{}
}

return slice, nil
}
Loading

0 comments on commit b0d39ed

Please sign in to comment.