Add DecodeSliceOfJSON to handle []Struct results easier
sgasho opened this issue · comments
(init idea: Add *RedisMessage.ScanSlice(dst any) to handle []Struct results easier)
When values of key1, key2 are both instances of X, code below returns an error of course because DecodeJSON handles only string
type X struct {
Name string
}
xs := make([]*X, 0)
if err := redisClient.Do(ctx, s.redisClient.B().Mget().Key("key1", "key2").Build()).DecodeJSON(xs); err != nil {
return err
}
I could not find any method to scan a slice of struct so I would like to add one, like "ScanSlice".
Scanning slice of struct in golang is not always easy so providing a scanning-slice method would be helpful.
some libraries, for example, sqlx.DB has a method "SelectContext" to scan a slice of struct and this is really helpful for us.
xs := make([]*X, 0)
if err := sqlx.DB.SelectContext(ctx, &xs, q, args...); err != nil { return err }
// -> xs = []&X{{Name: "name1"}, {Name: "name2"}, ....}
Hi @sgasho,
I know a ScanSlice
could be helpful, but what it should do, and how it does that is too vague. It seems to carry too many different expectations. Every time I use things like sqlx.DB.SelectContext
, I always wonder how will they meet my expectations and I sometimes find they don't.
I would prefer a much more clear API, for example a helper like this:
func DecodeSliceOfJSON[T any](resp rueidis.RedisResult, target *[]*T) error {
arr, err := resp.ToArray()
if err != nil {
return err
}
xs := make([]*T, len(arr))
for i, a := range arr {
if err = a.DecodeJSON(xs[i]); err != nil && !rueidis.IsRedisNil(err) {
return err
}
}
*target = xs
return nil
}
and you could use it like this
var xs []*X
err := DecodeSliceOfJSON(client.Do(context.Background(), client.B().Mget().Key("key1", "key2").Build()), &xs)
It seems to carry too many different expectations. Every time I use things like sqlx.DB.SelectContext, I always wonder how will they meet my expectations and I sometimes find they don't.
I see, and I found that key-value store has a higher degree of freedom than relational databases, which could lead more complicated implementation.
In fact, SelectContext uses the reflect package to do some pretty complicated things. That's a lot of work to maintain.
I would prefer a much more clear API, for example a helper like this:
I like it. that is so simple and no need to use reflect package. adding some error patterns makes it perfect.
Thanks for sharing your idea!