refactor: rstring - return a map from GetMany

This commit is contained in:
Anton
2024-04-11 13:59:56 +05:00
parent 4f7de216e5
commit 2c8eba045b
5 changed files with 37 additions and 21 deletions

View File

@@ -1,5 +1,7 @@
package command
import "github.com/nalgeon/redka"
// Atomically returns the string values of one or more keys.
// MGET key [key ...]
// https://redis.io/commands/mget
@@ -21,12 +23,22 @@ func parseMGet(b baseCmd) (*MGet, error) {
}
func (cmd *MGet) Run(w Writer, red Redka) (any, error) {
vals, err := red.Str().GetMany(cmd.keys...)
// Get the key-value map for requested keys.
items, err := red.Str().GetMany(cmd.keys...)
if err != nil {
w.WriteError(err.Error())
return nil, err
}
// Build the result slice.
// It will contain all values in the order of keys.
// Missing keys will have nil values.
vals := make([]redka.Value, len(cmd.keys))
for i, key := range cmd.keys {
vals[i] = items[key]
}
// Write the result.
w.WriteArray(len(vals))
for _, v := range vals {
if v.IsEmpty() {

View File

@@ -28,7 +28,7 @@ func (d *DB) Get(key string) (core.Value, error) {
}
// GetMany returns the values of multiple keys.
func (d *DB) GetMany(keys ...string) ([]core.Value, error) {
func (d *DB) GetMany(keys ...string) (map[string]core.Value, error) {
tx := NewTx(d.SQL)
return tx.GetMany(keys...)
}

View File

@@ -43,16 +43,22 @@ func TestStringGetMany(t *testing.T) {
tests := []struct {
name string
keys []string
want []redka.Value
want map[string]redka.Value
}{
{"all found", []string{"name", "age"},
[]redka.Value{redka.Value("alice"), redka.Value("25")},
map[string]redka.Value{
"name": redka.Value("alice"), "age": redka.Value("25"),
},
},
{"some found", []string{"name", "key1"},
[]redka.Value{redka.Value("alice"), redka.Value(nil)},
map[string]redka.Value{
"name": redka.Value("alice"), "key1": redka.Value(nil),
},
},
{"none found", []string{"key1", "key2"},
[]redka.Value{redka.Value(nil), redka.Value(nil)},
map[string]redka.Value{
"key1": redka.Value(nil), "key2": redka.Value(nil),
},
},
}
for _, tt := range tests {

View File

@@ -75,7 +75,14 @@ func (tx *Tx) Get(key string) (core.Value, error) {
}
// GetMany returns the values of multiple keys.
func (tx *Tx) GetMany(keys ...string) ([]core.Value, error) {
func (tx *Tx) GetMany(keys ...string) (map[string]core.Value, error) {
// Build a map of requested keys.
items := make(map[string]core.Value, len(keys))
for _, key := range keys {
items[key] = nil
}
// Get the values of the requested keys.
now := time.Now().UnixMilli()
query, keyArgs := sqlx.ExpandIn(sqlStringGetMany, ":keys", keys)
args := slices.Concat(keyArgs, []any{sql.Named("now", now)})
@@ -87,29 +94,20 @@ func (tx *Tx) GetMany(keys ...string) ([]core.Value, error) {
}
defer rows.Close()
// Build a map of known keys.
// It will be used to fill in the missing keys.
known := make(map[string]core.Value, len(keys))
// Fill the map with the values for existing keys
// (the rest of the keys will remain nil).
for rows.Next() {
key, val, err := scanValue(rows)
if err != nil {
return nil, err
}
known[key] = val
items[key] = val
}
if rows.Err() != nil {
return nil, rows.Err()
}
// Build the result slice.
// It will contain all values in the order of keys.
// Missing keys will have nil values.
vals := make([]core.Value, 0, len(keys))
for _, key := range keys {
vals = append(vals, known[key])
}
return vals, nil
return items, nil
}
// Set sets the key value. The key does not expire.

View File

@@ -48,7 +48,7 @@ type Keys interface {
// Strings is a string repository.
type Strings interface {
Get(key string) (Value, error)
GetMany(keys ...string) ([]Value, error)
GetMany(keys ...string) (map[string]Value, error)
Set(key string, value any) error
SetExpires(key string, value any, ttl time.Duration) error
SetNotExists(key string, value any, ttl time.Duration) (bool, error)