Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ See the [Usage Guide](./docs/usage.md) for installation, connecting, and a walkt
| [KEYS](./docs/keys.md) | Find keys matching a pattern |
| [CONFIG](./docs/config.md) | Read and modify server configuration |
| [TYPE](./docs/type.md) | Return the type of the value stored at a key |
| [EXISTS](./docs/exists.md) | Check if one or more keys exist |
22 changes: 22 additions & 0 deletions cmd/exists.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cmd

import (
"HelixDB/common"
)

// Exists returns the number of the given keys that exist in the store.
// If the same key is provided multiple times it is counted multiple times.
// Expired keys are treated as non-existent.
func Exists(command common.Cmd) ([]byte, error) {
if len(command.Args) < 1 {
err := common.WrongNumberOfArgsError(command.Name)
return common.RespError(err.Error()), err
}
count := 0
for _, key := range command.Args {
if _, err := GetValueFromMemory(key); err == nil {
count++
}
}
return common.RespInteger(count), nil
}
37 changes: 37 additions & 0 deletions cmd/exists_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package cmd

import (
"HelixDB/common"
"errors"
"reflect"
"testing"
)

func TestExists(t *testing.T) {
_, _ = Set(common.Cmd{Name: "SET", Args: []string{"ex_key1", "value1"}})
_, _ = Set(common.Cmd{Name: "SET", Args: []string{"ex_key2", "value2"}})

tests := []struct {
command common.Cmd
want []byte
wantErr error
}{
// Single existing key
{common.Cmd{Name: "EXISTS", Args: []string{"ex_key1"}}, common.RespInteger(1), nil},
// Single non-existent key
{common.Cmd{Name: "EXISTS", Args: []string{"no_such_key"}}, common.RespInteger(0), nil},
// Multiple keys, all exist
{common.Cmd{Name: "EXISTS", Args: []string{"ex_key1", "ex_key2"}}, common.RespInteger(2), nil},
// Multiple keys, some missing
{common.Cmd{Name: "EXISTS", Args: []string{"ex_key1", "no_such_key"}}, common.RespInteger(1), nil},
// Duplicate key counts multiple times
{common.Cmd{Name: "EXISTS", Args: []string{"ex_key1", "ex_key1"}}, common.RespInteger(2), nil},
// Wrong number of arguments
{common.Cmd{Name: "EXISTS"}, common.RespError("wrong number of arguments for 'exists' command"), common.ErrWrongNumberOfArgs},
}
for _, test := range tests {
if got, gotErr := Exists(test.command); !reflect.DeepEqual(got, test.want) || !errors.Is(gotErr, test.wantErr) {
t.Errorf("Exists(%v) = %v, %v; want %v, %v", test.command, got, gotErr, test.want, test.wantErr)
}
}
}
1 change: 1 addition & 0 deletions common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const Del = "DEL"
const Keys = "KEYS"
const Config = "CONFIG"
const Type = "TYPE"
const Exists = "EXISTS"

// Command Args
// Expiration Args
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
| [KEYS](./keys.md) | Find keys matching a pattern |
| [CONFIG](./config.md) | Read and modify server configuration |
| [TYPE](./type.md) | Return the type of the value stored at a key |
| [EXISTS](./exists.md) | Check if one or more keys exist |
50 changes: 50 additions & 0 deletions docs/exists.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# EXISTS

Returns the number of the given keys that exist in the store. Expired keys are treated as non-existent.

If the same key is provided multiple times it is counted multiple times.

## Syntax

```
EXISTS key [key ...]
```

## Arguments

| Argument | Type | Required | Description |
|----------|--------|----------|------------------------------|
| `key` | string | Yes | One or more keys to check. |

## Return value

The number of keys that exist. Ranges from `0` (none exist) to the total number of key arguments supplied.

## Errors

- `wrong number of arguments for 'exists' command` — when called with no arguments.

## Examples

```
> SET a 1
OK

> SET b 2
OK

> EXISTS a
1

> EXISTS a b
2

> EXISTS a missing
1

> EXISTS missing
0

> EXISTS a a
2
```
2 changes: 2 additions & 0 deletions exc/command_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ func ExecuteCommand(command common.Cmd) ([]byte, error) {
return cmd.ConfigCmd(command)
case common.Type:
return cmd.Type(command)
case common.Exists:
return cmd.Exists(command)
}
return []byte("-unsupported command\r\n"), UnsupportedCommand
}
Loading