Skip to content

Commit

Permalink
add HashCommands interface and tests for hash-related commands
Browse files Browse the repository at this point in the history
Signed-off-by: Umit Unal <[email protected]>
  • Loading branch information
umit committed Sep 4, 2024
1 parent 910bd5c commit 5da6299
Show file tree
Hide file tree
Showing 7 changed files with 924 additions and 1 deletion.
100 changes: 100 additions & 0 deletions go/api/base_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
// BaseClient defines an interface for methods common to both [GlideClient] and [GlideClusterClient].
type BaseClient interface {
StringCommands
HashCommands

// Close terminates the client by closing all associated resources.
Close()
Expand Down Expand Up @@ -199,3 +200,102 @@ func (client *baseClient) DecrBy(key string, amount int64) (int64, error) {
}
return handleLongResponse(result), nil
}

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

return handleStringOrNullResponse(result), nil
}

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

return handleStringMapResponse(result), nil
}

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

return handleStringArrayResponse(result), nil
}

func (client *baseClient) HSet(key string, fields map[string]string) (int64, error) {
result, err := client.executeCommand(C.HSet, utils.ConvertMapToKeyValueStringArray(key, fields))
if err != nil {
return 0, err
}

return handleIntegerOrNullResponse(result), nil
}

func (client *baseClient) HSetNX(key string, field string, value string) (bool, error) {
result, err := client.executeCommand(C.HSetNX, []string{key, field, value})
if err != nil {
return false, err
}

return handleBooleanResponse(result), nil
}

func (client *baseClient) HDel(key string, fields []string) (int64, error) {
result, err := client.executeCommand(C.HDel, append([]string{key}, fields...))
if err != nil {
return 0, err
}

return handleIntegerOrNullResponse(result), nil
}

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

return handleIntegerOrNullResponse(result), nil
}

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

return handleStringArrayResponse(result), nil
}

func (client *baseClient) HExists(key string, field string) (bool, error) {
result, err := client.executeCommand(C.HExists, []string{key, field})
if err != nil {
return false, err
}

return handleBooleanResponse(result), nil
}

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

return handleStringArrayResponse(result), nil
}

func (client *baseClient) HStrLen(key string, field string) (int64, error) {
result, err := client.executeCommand(C.HStrlen, []string{key, field})
if err != nil {
return 0, err
}

return handleIntegerOrNullResponse(result), nil
}
225 changes: 225 additions & 0 deletions go/api/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,228 @@ type StringCommands interface {
// [valkey.io]: https://valkey.io/commands/decrby/
DecrBy(key string, amount int64) (int64, error)
}

// HashCommands defines an interface for the "Hash Commands" group of commands for Valkey clients.
//
// See [valkey.io] for details.
//
// [valkey.io]: https://valkey.io/commands/?group=hash
type HashCommands interface {
// HGet returns the value associated with field in the hash stored at key.
//
// See [valkey.io] for details.
//
// For example:
//
// result, err := client.HGet("myhash", "field1")
//
// [valkey.io]: https://valkey.io/commands/hget/
HGet(key, field string) (string, error)

// HGetAll returns all fields and values of the hash stored at key.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash to retrieve.
//
// Return value:
// A map of all fields and their values in the hash, or an empty map when key does not exist.
//
// Complexity: O(N) where N is the size of the hash.
//
// Example:
// result, err := client.HGetAll("myhash")
// // result could be: map[string]string{"field1": "Hello", "field2": "World"}
//
// [valkey.io]: https://valkey.io/commands/hgetall/
HGetAll(key string) (map[string]string, error)

// HMGet returns the values associated with the specified fields in the hash stored at key.
//
// See [valkey.io] for details.
//
// For example:
//
// result, err := client.HMGet("myhash", []string{"field1", "field2", "nofield"})
//
// [valkey.io]: https://valkey.io/commands/hmget/
HMGet(key string, fields []string) ([]string, error)

// HSet sets the specified fields to their respective values in the hash stored at key.
// This command overwrites the values of specified fields that exist in the hash.
// If key doesn't exist, a new key holding a hash is created.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash.
// fields - A map of field-value pairs to set in the map.
//
// Return value:
// The number of fields that were added or updated.
//
// Complexity: O(1) for each field/value pair added, so O(N) to add N field/value pairs.
//
// Example:
// fieldsToSet := map[string]string{
// "field1": "Hello",
// "field2": "Hi",
// "field3": "World",
// }
// addedCount, err := client.HSet("myhash", fieldsToSet)
// // addedCount will be the number of fields added or updated
//
// [valkey.io]: https://valkey.io/commands/hset/
HSet(key string, fields map[string]string) (int64, error)

// HSetNX sets field in the hash stored at key to value, only if field does not yet exist.
// If key does not exist, a new key holding a hash is created.
// If field already exists, this operation has no effect.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash.
// field - The field to set.
// value - The value to set.
//
// Return value:
// 1 if field is a new field in the hash and value was set.
// 0 if field already exists in the hash and no operation was performed.
//
// Complexity: O(1)
//
// Example:

// result, err := client.HSetNX("myhash", "field", "Hello")
// // If field didn't exist, result will be 1
// // If field already existed, result will be 0
//
// [valkey.io]: https://valkey.io/commands/hsetnx/
HSetNX(key string, field string, value string) (bool, error)

// HDel removes the specified fields from the hash stored at key.
// Specified fields that do not exist within this hash are ignored.
// If key does not exist, it is treated as an empty hash and this command returns 0.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash.
// fields - One or more fields to remove from the hash.
//
// Return value:
// The number of fields that were removed from the hash, not including specified but non-existing fields.
//
// Complexity: O(N) where N is the number of fields to be removed.
//
// Example:
// removedCount, err := client.HDel("myhash", []string{"field1", "field2"})
// // removedCount will be the number of fields actually removed
//
// [valkey.io]: https://valkey.io/commands/hdel/
HDel(key string, fields []string) (int64, error)

// HLen returns the number of fields contained in the hash stored at key.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash.
//
// Return value:
// The number of fields in the hash, or 0 when key does not exist.
//
// Complexity: O(1)
//
// Example:
// length, err := client.HLen("myhash")
// // length will be the number of fields in the hash
//
// [valkey.io]: https://valkey.io/commands/hlen/
HLen(key string) (int64, error)

// HVals returns all values in the hash stored at key.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash.
//
// Return value:
// A slice of strings containing all the values in the hash, or an empty slice when key does not exist.
//
// Complexity: O(N) where N is the size of the hash.
//
// Example:
// values, err := client.HVals("myhash")
// // values will be a slice containing all the values in the hash
// // e.g., []string{"Hello", "World"}
//
// [valkey.io]: https://valkey.io/commands/hvals/
HVals(key string) ([]string, error)

// HExists returns if field is an existing field in the hash stored at key.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash.
// field - The field to check for existence.
//
// Return value:
// 1 if the hash contains field.
// 0 if the hash does not contain field, or key does not exist.
//
// Complexity: O(1)
//
// Example:
// exists, err := client.HExists("myhash", "field1")
// // exists will be 1 if the field exists, 0 otherwise
//
// [valkey.io]: https://valkey.io/commands/hexists/
HExists(key string, field string) (bool, error)

// HKeys returns all field names in the hash stored at key.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash.
//
// Return value:
// A slice of strings containing all the field names in the hash, or an empty slice when key does not exist.
//
// Complexity: O(N) where N is the size of the hash.
//
// Example:
// fieldNames, err := client.HKeys("myhash")
// // fieldNames will be a slice containing all the field names in the hash
// // e.g., []string{"field1", "field2"}
//
// [valkey.io]: https://valkey.io/commands/hkeys/
HKeys(key string) ([]string, error)

// HStrLen returns the string length of the value associated with field in the hash stored at key.
// If the key or the field do not exist, 0 is returned.
//
// See [valkey.io] for details.
//
// Parameters:
// key - The key of the hash.
// field - The field to get the string length of its value.
//
// Return value:
// The length of the string value associated with field, or 0 when field or key do not exist.
//
// Complexity: O(1)
//
// Example:
// length, err := client.HStrLen("myhash", "f1")
// // length will be the string length of the value associated with field "f1"
// // e.g., 10 for "HelloWorld"
//
// [valkey.io]: https://valkey.io/commands/hstrlen/
HStrLen(key string, field string) (int64, error)
}
Loading

0 comments on commit 5da6299

Please sign in to comment.