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
2 changes: 1 addition & 1 deletion temporal/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ tasks:
status:
- type mockery
cmds:
- go install github.com/vektra/mockery/v2@v2.38.0
Comment thread
shults marked this conversation as resolved.
- go install github.com/vektra/mockery/v2@v2.53.6
8 changes: 8 additions & 0 deletions temporal/internal/driver/redisv9/keyvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,14 @@ func (r *RedisV9) SetIfNotExist(ctx context.Context, key, value string, expirati
return res.Val(), nil
}

func (r *RedisV9) SetIfExist(ctx context.Context, key, value string, expiration time.Duration) (bool, error) {
if key == "" {
return false, temperr.KeyEmpty
}

return r.client.SetXX(ctx, key, value, expiration).Result()
}

func fetchKeysWithCursor(ctx context.Context,
client redis.UniversalClient,
pattern string,
Expand Down
49 changes: 49 additions & 0 deletions temporal/keyvalue/keyvalue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/TykTechnologies/storage/temporal/model"
"github.com/TykTechnologies/storage/temporal/temperr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestKeyValue_Set(t *testing.T) {
Expand Down Expand Up @@ -1351,3 +1352,51 @@ func TestKeyValue_SetIfNotExist(t *testing.T) {
}
}
}

func TestKeyValue_SetIfExist(t *testing.T) {
connectors := testutil.TestConnectors(t)
defer testutil.CloseConnectors(t, connectors)

for _, connector := range connectors {
t.Run(connector.Type(), func(t *testing.T) {
ctx := context.Background()
kv, err := NewKeyValue(connector)
require.Nil(t, err)

flusher, err := flusher.NewFlusher(connector)
assert.Nil(t, err)
defer assert.Nil(t, flusher.FlushAll(ctx))

t.Run("does not set key if key does not exist", func(t *testing.T) {
const key = "non_existent_key"
ok, err := kv.SetIfExist(t.Context(), key, "value", 0)
assert.False(t, ok)
assert.NoError(t, err)

_, err = kv.Get(t.Context(), key)
assert.ErrorIs(t, err, temperr.KeyNotFound)
})

t.Run("overrides key of already exists", func(t *testing.T) {
const key = "existent_key"

err := kv.Set(t.Context(), key, "value1", 0)
assert.NoError(t, err)

ok, err := kv.SetIfExist(t.Context(), key, "value2", 0)
assert.True(t, ok)
assert.NoError(t, err)

v, err := kv.Get(t.Context(), key)
assert.Equal(t, "value2", v)
assert.NoError(t, err)
})

t.Run("returns err if empty key was given", func(t *testing.T) {
ok, err := kv.SetIfExist(t.Context(), "", "1", 0)
assert.False(t, ok)
assert.ErrorIs(t, err, temperr.KeyEmpty)
})
})
}
}
3 changes: 3 additions & 0 deletions temporal/model/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ type KeyValue interface {
// SetIfNotExist sets the string value of a key if the key does not exist.
// Returns true if the key was set, false otherwise.
SetIfNotExist(ctx context.Context, key, value string, expiration time.Duration) (bool, error)
// SetIfExist sets the string value of a key if the key exists.
// Returns true if the key was set, false otherwise.
SetIfExist(ctx context.Context, key, value string, expiration time.Duration) (bool, error)
// Delete removes the specified keys
Delete(ctx context.Context, key string) error
// Increment atomically increments the integer value of a key by one
Expand Down
4 changes: 2 additions & 2 deletions temporal/tempmocks/connector.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion temporal/tempmocks/flusher.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 29 additions & 1 deletion temporal/tempmocks/key_value.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion temporal/tempmocks/list.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions temporal/tempmocks/message.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion temporal/tempmocks/option.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion temporal/tempmocks/queue.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion temporal/tempmocks/set.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion temporal/tempmocks/sorted_set.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions temporal/tempmocks/subscription.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading