diff --git a/set_commands.go b/set_commands.go index 79efa6e40..d13589638 100644 --- a/set_commands.go +++ b/set_commands.go @@ -6,6 +6,8 @@ import ( "github.com/redis/go-redis/v9/internal/hashtag" ) +// SetCmdable is an interface for Redis set commands. +// Sets are unordered collections of unique strings. type SetCmdable interface { SAdd(ctx context.Context, key string, members ...interface{}) *IntCmd SCard(ctx context.Context, key string) *IntCmd @@ -29,8 +31,13 @@ type SetCmdable interface { SUnionStore(ctx context.Context, destination string, keys ...string) *IntCmd } -//------------------------------------------------------------------------------ - +// SAdd Redis `SADD key member [member ...]` command. +// Adds the specified members to the set stored at key. +// Specified members that are already members of this set are ignored. +// If key does not exist, a new set is created before adding the specified members. +// +// Returns the number of elements that were added to the set, not including all +// the elements already present in the set. func (c cmdable) SAdd(ctx context.Context, key string, members ...interface{}) *IntCmd { args := make([]interface{}, 2, 2+len(members)) args[0] = "sadd" @@ -41,12 +48,21 @@ func (c cmdable) SAdd(ctx context.Context, key string, members ...interface{}) * return cmd } +// SCard Redis `SCARD key` command. +// Returns the set cardinality (number of elements) of the set stored at key. +// Returns 0 if key does not exist. func (c cmdable) SCard(ctx context.Context, key string) *IntCmd { cmd := NewIntCmd(ctx, "scard", key) _ = c(ctx, cmd) return cmd } +// SDiff Redis `SDIFF key [key ...]` command. +// Returns the members of the set resulting from the difference between the first set +// and all the successive sets. +// Keys that do not exist are considered to be empty sets. +// +// Returns a slice of members of the resulting set. func (c cmdable) SDiff(ctx context.Context, keys ...string) *StringSliceCmd { args := make([]interface{}, 1+len(keys)) args[0] = "sdiff" @@ -58,6 +74,12 @@ func (c cmdable) SDiff(ctx context.Context, keys ...string) *StringSliceCmd { return cmd } +// SDiffStore Redis `SDIFFSTORE destination key [key ...]` command. +// Stores the members of the set resulting from the difference between the first set +// and all the successive sets into destination. +// If destination already exists, it is overwritten. +// +// Returns the number of elements in the resulting set. func (c cmdable) SDiffStore(ctx context.Context, destination string, keys ...string) *IntCmd { args := make([]interface{}, 2+len(keys)) args[0] = "sdiffstore" @@ -70,6 +92,12 @@ func (c cmdable) SDiffStore(ctx context.Context, destination string, keys ...str return cmd } +// SInter Redis `SINTER key [key ...]` command. +// Returns the members of the set resulting from the intersection of all the given sets. +// Keys that do not exist are considered to be empty sets. +// With one of the keys being an empty set, the resulting set is also empty. +// +// Returns a slice of members of the resulting set. func (c cmdable) SInter(ctx context.Context, keys ...string) *StringSliceCmd { args := make([]interface{}, 1+len(keys)) args[0] = "sinter" @@ -81,6 +109,15 @@ func (c cmdable) SInter(ctx context.Context, keys ...string) *StringSliceCmd { return cmd } +// SInterCard Redis `SINTERCARD numkeys key [key ...] [LIMIT limit]` command. +// Returns the cardinality of the set resulting from the intersection of all the given sets. +// Keys that do not exist are considered to be empty sets. +// With one of the keys being an empty set, the resulting set is also empty. +// +// The limit parameter sets an upper bound on the number of results returned. +// If limit is 0, no limit is applied. +// +// Returns the number of elements in the resulting set. func (c cmdable) SInterCard(ctx context.Context, limit int64, keys ...string) *IntCmd { numKeys := len(keys) args := make([]interface{}, 4+numKeys) @@ -96,6 +133,12 @@ func (c cmdable) SInterCard(ctx context.Context, limit int64, keys ...string) *I return cmd } +// SInterStore Redis `SINTERSTORE destination key [key ...]` command. +// Stores the members of the set resulting from the intersection of all the given sets +// into destination. +// If destination already exists, it is overwritten. +// +// Returns the number of elements in the resulting set. func (c cmdable) SInterStore(ctx context.Context, destination string, keys ...string) *IntCmd { args := make([]interface{}, 2+len(keys)) args[0] = "sinterstore" @@ -108,6 +151,10 @@ func (c cmdable) SInterStore(ctx context.Context, destination string, keys ...st return cmd } +// SIsMember Redis `SISMEMBER key member` command. +// Returns if member is a member of the set stored at key. +// Returns true if the element is a member of the set, false if it is not a member +// or if key does not exist. func (c cmdable) SIsMember(ctx context.Context, key string, member interface{}) *BoolCmd { cmd := NewBoolCmd(ctx, "sismember", key, member) _ = c(ctx, cmd) @@ -115,6 +162,11 @@ func (c cmdable) SIsMember(ctx context.Context, key string, member interface{}) } // SMIsMember Redis `SMISMEMBER key member [member ...]` command. +// Returns whether each member is a member of the set stored at key. +// For each member, returns true if the element is a member of the set, false if it is not +// a member or if key does not exist. +// +// Returns a slice of booleans, one for each member, indicating membership. func (c cmdable) SMIsMember(ctx context.Context, key string, members ...interface{}) *BoolSliceCmd { args := make([]interface{}, 2, 2+len(members)) args[0] = "smismember" @@ -126,6 +178,10 @@ func (c cmdable) SMIsMember(ctx context.Context, key string, members ...interfac } // SMembers Redis `SMEMBERS key` command output as a slice. +// Returns all the members of the set value stored at key. +// Returns an empty slice if key does not exist. +// +// Returns a slice of all members of the set. func (c cmdable) SMembers(ctx context.Context, key string) *StringSliceCmd { cmd := NewStringSliceCmd(ctx, "smembers", key) _ = c(ctx, cmd) @@ -133,12 +189,23 @@ func (c cmdable) SMembers(ctx context.Context, key string) *StringSliceCmd { } // SMembersMap Redis `SMEMBERS key` command output as a map. +// Returns all the members of the set value stored at key as a map. +// Returns an empty map if key does not exist. +// +// Returns a map where keys are the set members and values are empty structs. func (c cmdable) SMembersMap(ctx context.Context, key string) *StringStructMapCmd { cmd := NewStringStructMapCmd(ctx, "smembers", key) _ = c(ctx, cmd) return cmd } +// SMove Redis `SMOVE source destination member` command. +// Moves member from the set at source to the set at destination. +// This operation is atomic. In every given moment the element will appear to be a member +// of source or destination for other clients. +// +// Returns true if the element is moved, false if the element is not a member of source +// and no operation was performed. func (c cmdable) SMove(ctx context.Context, source, destination string, member interface{}) *BoolCmd { cmd := NewBoolCmd(ctx, "smove", source, destination, member) _ = c(ctx, cmd) @@ -146,6 +213,10 @@ func (c cmdable) SMove(ctx context.Context, source, destination string, member i } // SPop Redis `SPOP key` command. +// Removes and returns one or more random members from the set value stored at key. +// This version returns a single random member. +// +// Returns the removed member, or nil if key does not exist. func (c cmdable) SPop(ctx context.Context, key string) *StringCmd { cmd := NewStringCmd(ctx, "spop", key) _ = c(ctx, cmd) @@ -153,6 +224,10 @@ func (c cmdable) SPop(ctx context.Context, key string) *StringCmd { } // SPopN Redis `SPOP key count` command. +// Removes and returns one or more random members from the set value stored at key. +// This version returns up to count random members. +// +// Returns a slice of removed members. If key does not exist, returns an empty slice. func (c cmdable) SPopN(ctx context.Context, key string, count int64) *StringSliceCmd { cmd := NewStringSliceCmd(ctx, "spop", key, count) _ = c(ctx, cmd) @@ -160,6 +235,10 @@ func (c cmdable) SPopN(ctx context.Context, key string, count int64) *StringSlic } // SRandMember Redis `SRANDMEMBER key` command. +// Returns a random member from the set value stored at key. +// This version returns a single random member without removing it. +// +// Returns the random member, or nil if key does not exist or the set is empty. func (c cmdable) SRandMember(ctx context.Context, key string) *StringCmd { cmd := NewStringCmd(ctx, "srandmember", key) _ = c(ctx, cmd) @@ -167,12 +246,25 @@ func (c cmdable) SRandMember(ctx context.Context, key string) *StringCmd { } // SRandMemberN Redis `SRANDMEMBER key count` command. +// Returns an array of random members from the set value stored at key. +// This version returns up to count random members without removing them. +// When called with a positive count, returns distinct elements. +// When called with a negative count, allows for repeated elements. +// +// Returns a slice of random members. If key does not exist, returns an empty slice. func (c cmdable) SRandMemberN(ctx context.Context, key string, count int64) *StringSliceCmd { cmd := NewStringSliceCmd(ctx, "srandmember", key, count) _ = c(ctx, cmd) return cmd } +// SRem Redis `SREM key member [member ...]` command. +// Removes the specified members from the set stored at key. +// Specified members that are not a member of this set are ignored. +// If key does not exist, it is treated as an empty set and this command returns 0. +// +// Returns the number of members that were removed from the set, not including +// non-existing members. func (c cmdable) SRem(ctx context.Context, key string, members ...interface{}) *IntCmd { args := make([]interface{}, 2, 2+len(members)) args[0] = "srem" @@ -183,6 +275,11 @@ func (c cmdable) SRem(ctx context.Context, key string, members ...interface{}) * return cmd } +// SUnion Redis `SUNION key [key ...]` command. +// Returns the members of the set resulting from the union of all the given sets. +// Keys that do not exist are considered to be empty sets. +// +// Returns a slice of members of the resulting set. func (c cmdable) SUnion(ctx context.Context, keys ...string) *StringSliceCmd { args := make([]interface{}, 1+len(keys)) args[0] = "sunion" @@ -194,6 +291,12 @@ func (c cmdable) SUnion(ctx context.Context, keys ...string) *StringSliceCmd { return cmd } +// SUnionStore Redis `SUNIONSTORE destination key [key ...]` command. +// Stores the members of the set resulting from the union of all the given sets +// into destination. +// If destination already exists, it is overwritten. +// +// Returns the number of elements in the resulting set. func (c cmdable) SUnionStore(ctx context.Context, destination string, keys ...string) *IntCmd { args := make([]interface{}, 2+len(keys)) args[0] = "sunionstore" @@ -206,6 +309,17 @@ func (c cmdable) SUnionStore(ctx context.Context, destination string, keys ...st return cmd } +// SScan Redis `SSCAN key cursor [MATCH pattern] [COUNT count]` command. +// Incrementally iterates the set elements stored at key. +// This is a cursor-based iterator that allows scanning large sets efficiently. +// +// Parameters: +// - cursor: The cursor value for the iteration (use 0 to start a new scan) +// - match: Optional pattern to match elements (empty string means no pattern) +// - count: Optional hint about how many elements to return per iteration +// +// Returns a ScanCmd that can be used to iterate through all members of the set. +// Use the returned cursor from each iteration to continue scanning. func (c cmdable) SScan(ctx context.Context, key string, cursor uint64, match string, count int64) *ScanCmd { args := []interface{}{"sscan", key, cursor} if match != "" {