Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate GETEX and GETDEL commands #1061

Merged
merged 18 commits into from
Nov 4, 2024
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
41 changes: 13 additions & 28 deletions docs/src/content/docs/commands/GETDEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,12 @@ GETDEL key

## Behaviour

When the `GETDEL` command is executed, the following steps occur:
1. The command checks if the specified key exists in the DiceDB database.
2. If the key exists, the value associated with the key is retrieved.
3. The key is then deleted from the database.
4. The retrieved value is returned to the client.
5. If the key does not exist, `nil` is returned, and no deletion occurs.
- If the specified key exists, `GETDEL` retrieves its value and then deletes the key from the database.
- The retrieved value is returned to the client.
- If the key does not exist, `GETDEL` returns `nil` and no deletion is performed.

## Errors

The `GETDEL` command can raise errors in the following scenarios:

1. `Wrong Type Error`:

- Error Message: `ERROR WRONGTYPE Operation against a key holding the wrong kind of value`
Expand All @@ -47,9 +42,11 @@ The `GETDEL` command can raise errors in the following scenarios:
- Error Message: `ERROR wrong number of arguments for 'getdel' command`
- Occurs if the command is called without the required parameter.

## Examples
## Example Usage

### Retreive and Delete an Existing Key

### Example with Existent key
Setting a key `mykey` with the value `"Hello, World!"` and then using `GETDEL` to retrieve and delete it.

```bash
127.0.0.1:7379> SET mykey "Hello, World!"
Expand All @@ -60,34 +57,22 @@ OK
(nil)
```

`Explanation:`
### Using `GETDEL` on a Non-Existent Key

- The key `mykey` is set with the value `"Hello, World!"`.
- The `GETDEL` command retrieves the value `"Hello, World!"` and deletes the key `mykey` from the database.
- The `GET` command attempts to retrieve the value associated with the key `mykey` and returns `nil` as the key no longer exists.

### Example with a Non-Existent Key
Trying to retrieve and delete a key `nonexistingkey` that does not exist.

```bash
127.0.0.1:7379> GETDEL nonexistingkey
(nil)
```

`Explanation:`

- The key `nonexistingkey` does not exist in the database.
- The `GETDEL` command returns `nil` since the key is not found.
### Using `GETDEL` on a Key with a Different Data Type

### Example with a Wrong Type of Key
Setting a key `mylist` as a list and then trying to use `GETDEL`, which is incompatible with non-string data types.

```bash
127.0.0.1:7379> LPUSH mylist "item1"
(integer) 1
127.0.0.1:7379> GETDEL mylist
ERROR WRONGTYPE Operation against a key holding the wrong kind of value
```

`Explanation:`

- The key `mylist` is a list, not a string.
- The `GETDEL` command raises a `WRONGTYPE` error because it expects the key to be a string.
(error) WRONGTYPE Operation against a key holding the wrong kind of value
```
52 changes: 27 additions & 25 deletions docs/src/content/docs/commands/GETEX.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: GETEX
description: Documentation for the DiceDB command GETEX
description: The `GETEX` command in DiceDB is used to retrieve the value of a specified key and simultaneously set its expiration time. This command is particularly useful when you want to access the value of a key and ensure that it expires after a certain period, all in a single atomic operation.
---

The `GETEX` command in DiceDB is used to retrieve the value of a specified key and simultaneously set its expiration time. This command is particularly useful when you want to access the value of a key and ensure that it expires after a certain period, all in a single atomic operation.
Expand Down Expand Up @@ -32,29 +32,33 @@ GETEX key [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp

## Behaviour

When the `GETEX` command is executed, it performs the following actions:
- If the specified key does not exist, `GETEX` will return nil, and no expiration time will be set.
- If the key exists, `GETEX` retrieves and returns its current value.
- When used with the `EX`, `PX`, `EXAT`, or `PXAT` options, `GETEX` will adjust the key's expiration time according to the specified option.
- Using the `PERSIST` option removes any existing expiration, making the key persist indefinitely.

1. Retrieves the value of the specified key.
2. Sets the expiration time for the key based on the provided option (`EX`, `PX`, `EXAT`, `PXAT`, or `PERSIST`).
3. Returns the value of the key.
## Errors

If the key does not exist, the command will return `nil` and no expiration time will be set.
1. `Wrong number of arguments`:

## Errors
- Error Message: `(error) ERR wrong number of arguments for 'getex' command`
- Occurs when the command is executed with an incorrect number of arguments.

2. `Invalid expiration option`:

The `GETEX` command can raise errors in the following scenarios:
- Error Message: `(error) ERR syntax error`
- Occurs when an unrecognized or incorrect expiration option is specified.

1. `Wrong number of arguments`: If the command is not provided with the correct number of arguments, it will return an error.
- Error message: `(error) ERR wrong number of arguments for 'getex' command`
2. `Invalid expiration option`: If an invalid expiration option is provided, it will return an error.
- Error message: `(error) ERR syntax error`
3. `Invalid expiration time`: If the expiration time is not a valid integer or timestamp, it will return an error.
- Error message: `(error) ERR value is not an integer or out of range`
3. `Invalid expiration time`:

- Error Message: `(error) ERR value is not an integer or out of range`
- Occurs when the expiration time provided is not a valid integer or timestamp.

## Example Usage

### Example 1: Retrieve value and set expiration in seconds
### Retrieve value and set expiration in seconds

This command will return `"Hello"` and set the expiration time of `mykey` to 10 seconds.

```bash
127.0.0.1:7379> SET mykey "Hello"
Expand All @@ -63,9 +67,9 @@ OK
127.0.0.1:7379> "Hello"
```

- This command will return `"Hello"` and set the expiration time of `mykey` to 10 seconds.
### Retrieve value and set expiration in milliseconds

### Example 2: Retrieve value and set expiration in milliseconds
This command will return `"Hello"` and set the expiration time of `mykey` to 10,000 milliseconds (10 seconds).

```bash
127.0.0.1:7379> SET mykey "Hello"
Expand All @@ -74,9 +78,9 @@ OK
127.0.0.1:7379> "Hello"
```

- This command will return `"Hello"` and set the expiration time of `mykey` to 10,000 milliseconds (10 seconds).
### Retrieve value and set expiration as Unix timestamp in seconds

### Example 3: Retrieve value and set expiration as Unix timestamp in seconds
This command will return `"Hello"` and set the expiration time of `mykey` to the Unix timestamp `1672531199`.

```bash
127.0.0.1:7379> SET mykey "Hello"
Expand All @@ -85,9 +89,9 @@ OK
127.0.0.1:7379> "Hello"
```

- This command will return `"Hello"` and set the expiration time of `mykey` to the Unix timestamp `1672531199`.
### Retrieve value and set expiration as Unix timestamp in milliseconds

### Example 4: Retrieve value and set expiration as Unix timestamp in milliseconds
This command will return `"Hello"` and set the expiration time of `mykey` to the Unix timestamp `1672531199000` milliseconds.

```bash
127.0.0.1:7379> SET mykey "Hello"
Expand All @@ -96,9 +100,9 @@ OK
127.0.0.1:7379> "Hello"
```

- This command will return `"Hello"` and set the expiration time of `mykey` to the Unix timestamp `1672531199000` milliseconds.
### Retrieve value and remove expiration

### Example 5: Retrieve value and remove expiration
This command will return `"Hello"` and remove the expiration time of `mykey`, making it persistent.

```bash
127.0.0.1:7379> SET mykey "Hello"
Expand All @@ -109,8 +113,6 @@ OK
127.0.0.1:7379> "Hello"
```

- This command will return `"Hello"` and remove the expiration time of `mykey`, making it persistent.

## Notes

- The `GETEX` command is atomic, meaning it ensures that the retrieval of the value and the setting of the expiration time happen as a single, indivisible operation.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package async
package resp

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"gotest.tools/v3/assert"
)

func TestGetDel(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package async
package resp

import (
"strconv"
"testing"
"time"

"github.com/stretchr/testify/assert"
"gotest.tools/v3/assert"
)

func TestGetEx(t *testing.T) {
Expand Down Expand Up @@ -147,7 +147,6 @@ func TestGetEx(t *testing.T) {

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// deleteTestKeys([]string{"foo"}, store)
FireCommand(conn, "DEL foo")

for i, cmd := range tc.commands {
Expand All @@ -156,9 +155,9 @@ func TestGetEx(t *testing.T) {
}
result := FireCommand(conn, cmd)
if tc.assertType[i] == "equal" {
assert.Equal(t, tc.expected[i], result)
assert.DeepEqual(t, tc.expected[i], result)
} else if tc.assertType[i] == "assert" {
assert.True(t, result.(int64) <= tc.expected[i].(int64), "Expected %v to be less than or equal to %v", result, tc.expected[i])
assert.Assert(t, result.(int64) <= tc.expected[i].(int64), "Expected %v to be less than or equal to %v", result, tc.expected[i])
}
}
})
Expand Down
14 changes: 8 additions & 6 deletions internal/eval/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ var (
The key should be the only param in args And If the key exists, it will be deleted before its value is returned.
The RESP value of the key is encoded and then returned
GETDEL returns RespNIL if key is expired or it does not exist`,
Eval: evalGETDEL,
Arity: 2,
KeySpecs: KeySpecs{BeginIndex: 1},
Arity: 2,
KeySpecs: KeySpecs{BeginIndex: 1},
IsMigrated: true,
NewEval: evalGETDEL,
}
msetCmdMeta = DiceCmdMeta{
Name: "MSET",
Expand Down Expand Up @@ -678,9 +679,10 @@ var (
Name: "GETEX",
Info: `Get the value of key and optionally set its expiration.
GETEX is similar to GET, but is a write command with additional options.`,
Eval: evalGETEX,
Arity: -2,
KeySpecs: KeySpecs{BeginIndex: 1},
Arity: -2,
KeySpecs: KeySpecs{BeginIndex: 1},
IsMigrated: true,
NewEval: evalGETEX,
}
pttlCmdMeta = DiceCmdMeta{
Name: "PTTL",
Expand Down
1 change: 1 addition & 0 deletions internal/eval/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (

Ex string = "EX"
Px string = "PX"
Persist string = "PERSIST"
Pxat string = "PXAT"
Exat string = "EXAT"
XX string = "XX"
Expand Down
Loading