forked from DiceDB/dice
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DiceDB#1018 Migration: Append, GetRange (DiceDB#1095)
- Loading branch information
1 parent
8fdab8a
commit 4e34f46
Showing
15 changed files
with
1,020 additions
and
345 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
--- | ||
title: APPEND | ||
description: The `APPEND` command in DiceDB is used to either set the value of a key or append a value to an existing key. This command allows for both creating and updating key-value pairs. | ||
--- | ||
The `APPEND` command in DiceDB is used to either set the value of a key or append a value to an existing key. This command allows for both creating and updating key-value pairs. | ||
|
||
## Syntax | ||
|
||
```bash | ||
APPEND key value | ||
``` | ||
|
||
## Parameters | ||
| Parameter | Description | Type | Required | | ||
|-----------|---------------------------------------------------------------------------|---------|----------| | ||
| `key` | The name of the key to be set. | String | Yes | | ||
| `value` | The value to be set for the key. | String | Yes | | ||
|
||
## Return values | ||
|
||
| Condition | Return Value | | ||
|------------------------------------------------|---------------------------------------------------| | ||
| if key is set successfully | length of the string. | | ||
|
||
## Behaviour | ||
- If the specified key does not exist, the `APPEND` command will create a new key-value pair. | ||
- If the specified key already exists, the `APPEND` command will append the value to the existing value of the key. | ||
|
||
|
||
## Errors | ||
1. `Wrong type of value or key`: | ||
|
||
- Error Message: `(error) ERROR WRONGTYPE Operation against a key holding the wrong kind of value` | ||
- Occurs when attempting to use the command on a key that contains a non-string value. | ||
|
||
2. `Invalid syntax or conflicting options`: | ||
|
||
- Error Message: `(error) ERROR wrong number of arguments for 'append' command` | ||
- If the number of arguments are not exactly equal to 2. | ||
|
||
## Example Usage | ||
|
||
### Basic Usage | ||
|
||
Setting a key `foo` with the value `bar` using `APPEND` | ||
|
||
```bash | ||
127.0.0.1:7379> APPEND foo bar | ||
(integer) 3 | ||
``` | ||
|
||
Appending to key `foo` that contains `bar` with `baz` | ||
|
||
```bash | ||
127.0.0.1:7379> SET foo bar | ||
127.0.0.1:7379> APPEND foo baz | ||
(integer) 6 | ||
``` | ||
|
||
### Invalid usage | ||
|
||
Trying to use `APPEND` without giving the value | ||
|
||
```bash | ||
127.0.0.1:7379> APPEND foo | ||
(error) ERROR wrong number of arguments for 'append' command | ||
``` | ||
Trying to use `APPEND` on a invalid data type. | ||
```bash | ||
127.0.0.1:7379> LPUSH foo bar | ||
127.0.0.1:7379> APPEND foo baz | ||
(error) ERROR WRONGTYPE Operation against a key holding the wrong kind of value | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
--- | ||
title: GETRANGE | ||
description: The `GETRANGE` command in DiceDB is used to get a substring of a string, provided the start and end indices | ||
--- | ||
The `GETRANGE` command in DiceDB is used to get a substring of a string, provided the start and end indices. | ||
|
||
## Syntax | ||
|
||
```bash | ||
GETRANGE key start end | ||
``` | ||
|
||
## Parameters | ||
| Parameter | Description | Type | Required | | ||
|-----------|---------------------------------------------------------------------------|---------|----------| | ||
| `key` | The name of the key containing the string. | String | Yes | | ||
| `start` | The starting index of the required substring. | Integer | Yes | | ||
| `end` | The ending index of the required substring. | Integer | Yes | | ||
## Return values | ||
|
||
| Condition | Return Value | | ||
|------------------------------------------------|---------------------------------------------------| | ||
| if key contains a valid string | a substring based on the start and end indices | | ||
| if `start` is greater than `end` | an empty string is returned | | ||
| if the `end` exceeds the length of the string present at `key` | the entire string is returned | | ||
| if the `start` is greater than the length of the string | an empty string is returned. | | ||
|
||
## Behaviour | ||
- If the specified key does not exist, the `GETRANGE` command returns an empty string. | ||
- If `start` is greater than `end`, the `GETRANGE` command returns an empty string. | ||
- If `start` is not within the length of the string, the `GETRANGE` command returns an empty string. | ||
- `start` and `end` can be negative which removed `end + 1` characters from the other side of the string. | ||
- Both `start` and `end` can be negative, which removes characters from the string, starting from the `end + 1` position on the right. | ||
|
||
## Errors | ||
1. `Wrong type of value or key`: | ||
|
||
- Error Message: `(error) ERROR WRONGTYPE Operation against a key holding the wrong kind of value` | ||
- Occurs when attempting to use the command on a key that contains a non-string value. | ||
|
||
2. `Invalid syntax or conflicting options`: | ||
|
||
- Error Message: `(error) ERROR wrong number of arguments for 'GETRANGE' command` | ||
- If the number of arguments are not exactly equal to 4. | ||
|
||
3. `Invalid input type for start and end` | ||
|
||
- Error Message: `(error) ERROR value is not an integer or out of range` | ||
- If `start` and `end` are not integers. | ||
|
||
## Example Usage | ||
|
||
### Basic Usage | ||
|
||
Assume we have a string stored in `foo` | ||
|
||
```bash | ||
127.0.0.1:7379> SET foo apple | ||
OK | ||
``` | ||
|
||
```bash | ||
127.0.0.1:7379> GETRANGE foo 1 3 | ||
"ppl" | ||
``` | ||
|
||
```bash | ||
127.0.0.1:7379> GETRANGE foo 0 -1 | ||
"apple" | ||
``` | ||
|
||
```bash | ||
127.0.0.1:7379> GETRANGE foo 0 -10 | ||
"" | ||
``` | ||
|
||
```bash | ||
127.0.0.1:7379> GETRANGE foo 0 -2 | ||
"appl" | ||
``` | ||
|
||
```bash | ||
127.0.0.1:7379> GETRANGE foo 0 1001 | ||
"apple" | ||
``` | ||
|
||
### Invalid usage | ||
|
||
Trying to use `GETRANGE` without giving the value | ||
|
||
```bash | ||
127.0.0.1:7379> GETRANGE foo | ||
(error) ERROR wrong number of arguments for 'getrange' command | ||
``` | ||
|
||
Trying to use `GETRANGE` on an invalid data type. | ||
|
||
```bash | ||
127.0.0.1:7379> LPUSH foo apple | ||
127.0.0.1:7379> GETRANGE foo 0 5 | ||
(error) ERROR WRONGTYPE Operation against a key holding the wrong kind of value | ||
``` | ||
|
||
```bash | ||
127.0.0.1:7379> GETRANGE foo s e | ||
(error) ERROR value is not an integer or out of range | ||
``` |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package http | ||
|
||
import ( | ||
"testing" | ||
|
||
testifyAssert "github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestAPPEND(t *testing.T) { | ||
exec := NewHTTPCommandExecutor() | ||
testCases := []struct { | ||
name string | ||
commands []HTTPCommand | ||
expected []interface{} | ||
cleanup []HTTPCommand | ||
}{ | ||
{ | ||
name: "APPEND and GET a new Val", | ||
commands: []HTTPCommand{ | ||
{Command: "APPEND", Body: map[string]interface{}{"key": "k", "value": "newVal"}}, | ||
{Command: "GET", Body: map[string]interface{}{"key": "k"}}, | ||
}, | ||
expected: []interface{}{float64(6), "newVal"}, | ||
cleanup: []HTTPCommand{ | ||
{Command: "del", Body: map[string]interface{}{"key": "k"}}, | ||
}, | ||
}, | ||
{ | ||
name: "APPEND to an exisiting key and GET", | ||
commands: []HTTPCommand{ | ||
{Command: "SET", Body: map[string]interface{}{"key": "k", "value": "Bhima"}}, | ||
{Command: "APPEND", Body: map[string]interface{}{"key": "k", "value": "Shankar"}}, | ||
{Command: "GET", Body: map[string]interface{}{"key": "k"}}, | ||
}, | ||
expected: []interface{}{"OK", float64(12), "BhimaShankar"}, | ||
cleanup: []HTTPCommand{ | ||
{Command: "del", Body: map[string]interface{}{"key": "k"}}, | ||
}, | ||
}, | ||
{ | ||
name: "APPEND without input value", | ||
commands: []HTTPCommand{ | ||
{Command: "APPEND", Body: map[string]interface{}{"key": "k"}}, | ||
}, | ||
expected: []interface{}{"ERR wrong number of arguments for 'append' command"}, | ||
cleanup: []HTTPCommand{ | ||
{Command: "del", Body: map[string]interface{}{"key": "k"}}, | ||
}, | ||
}, | ||
{ | ||
name: "APPEND empty string to an exsisting key with empty string", | ||
commands: []HTTPCommand{ | ||
{Command: "SET", Body: map[string]interface{}{"key": "k", "value": ""}}, | ||
{Command: "APPEND", Body: map[string]interface{}{"key": "k", "value": ""}}, | ||
}, | ||
expected: []interface{}{"OK", float64(0)}, | ||
cleanup: []HTTPCommand{ | ||
{Command: "del", Body: map[string]interface{}{"key": "k"}}, | ||
}, | ||
}, | ||
{ | ||
name: "APPEND to key created using LPUSH", | ||
commands: []HTTPCommand{ | ||
{Command: "LPUSH", Body: map[string]interface{}{"key": "m", "value": "bhima"}}, | ||
{Command: "APPEND", Body: map[string]interface{}{"key": "m", "value": "shankar"}}, | ||
}, | ||
expected: []interface{}{float64(1), "WRONGTYPE Operation against a key holding the wrong kind of value"}, | ||
cleanup: []HTTPCommand{ | ||
{Command: "del", Body: map[string]interface{}{"key": "m"}}, | ||
}, | ||
}, | ||
{ | ||
name: "APPEND value with leading zeros", | ||
commands: []HTTPCommand{ | ||
{Command: "APPEND", Body: map[string]interface{}{"key": "z", "value": "0043"}}, | ||
}, | ||
expected: []interface{}{float64(4)}, | ||
cleanup: []HTTPCommand{ | ||
{Command: "del", Body: map[string]interface{}{"key": "z"}}, | ||
}, | ||
}, | ||
{ | ||
name: "APPEND to key created using SADD", | ||
commands: []HTTPCommand{ | ||
{Command: "SADD", Body: map[string]interface{}{"key": "key", "value": "apple"}}, | ||
{Command: "APPEND", Body: map[string]interface{}{"key": "key", "value": "banana"}}, | ||
}, | ||
expected: []interface{}{float64(1), "WRONGTYPE Operation against a key holding the wrong kind of value"}, | ||
cleanup: []HTTPCommand{ | ||
{Command: "del", Body: map[string]interface{}{"key": "key"}}, | ||
}, | ||
}, | ||
} | ||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
|
||
for i, cmd := range tc.commands { | ||
result, _ := exec.FireCommand(cmd) | ||
testifyAssert.Equal(t, tc.expected[i], result) | ||
} | ||
exec.FireCommand(tc.cleanup[0]) | ||
}) | ||
} | ||
} |
Oops, something went wrong.