mirror of https://github.com/go-redis/redis.git
Allow scanning redis values into pointer fields (#2787)
* Allow scanning redis values into pointer fields * Formatting --------- Co-authored-by: Ilia Personal <iliapersonal@Ilyas-MBP.station> Co-authored-by: ofekshenawa <104765379+ofekshenawa@users.noreply.github.com>
This commit is contained in:
parent
716906adda
commit
c828764336
|
@ -5378,7 +5378,6 @@ func (cmd *InfoCmd) readReply(rd *proto.Reader) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *InfoCmd) Item(section, key string) string {
|
func (cmd *InfoCmd) Item(section, key string) string {
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
|
|
||||||
. "github.com/bsm/ginkgo/v2"
|
. "github.com/bsm/ginkgo/v2"
|
||||||
. "github.com/bsm/gomega"
|
. "github.com/bsm/gomega"
|
||||||
|
|
||||||
|
"github.com/redis/go-redis/v9/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type data struct {
|
type data struct {
|
||||||
|
@ -29,6 +31,7 @@ type data struct {
|
||||||
Float float32 `redis:"float"`
|
Float float32 `redis:"float"`
|
||||||
Float64 float64 `redis:"float64"`
|
Float64 float64 `redis:"float64"`
|
||||||
Bool bool `redis:"bool"`
|
Bool bool `redis:"bool"`
|
||||||
|
BoolRef *bool `redis:"boolRef"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimeRFC3339Nano struct {
|
type TimeRFC3339Nano struct {
|
||||||
|
@ -117,10 +120,10 @@ var _ = Describe("Scan", func() {
|
||||||
Expect(Scan(&d, i{"key"}, i{"value"})).NotTo(HaveOccurred())
|
Expect(Scan(&d, i{"key"}, i{"value"})).NotTo(HaveOccurred())
|
||||||
Expect(d).To(Equal(data{}))
|
Expect(d).To(Equal(data{}))
|
||||||
|
|
||||||
keys := i{"string", "byte", "int", "int64", "uint", "uint64", "float", "float64", "bool"}
|
keys := i{"string", "byte", "int", "int64", "uint", "uint64", "float", "float64", "bool", "boolRef"}
|
||||||
vals := i{
|
vals := i{
|
||||||
"str!", "bytes!", "123", "123456789123456789", "456", "987654321987654321",
|
"str!", "bytes!", "123", "123456789123456789", "456", "987654321987654321",
|
||||||
"123.456", "123456789123456789.987654321987654321", "1",
|
"123.456", "123456789123456789.987654321987654321", "1", "1",
|
||||||
}
|
}
|
||||||
Expect(Scan(&d, keys, vals)).NotTo(HaveOccurred())
|
Expect(Scan(&d, keys, vals)).NotTo(HaveOccurred())
|
||||||
Expect(d).To(Equal(data{
|
Expect(d).To(Equal(data{
|
||||||
|
@ -133,6 +136,7 @@ var _ = Describe("Scan", func() {
|
||||||
Float: 123.456,
|
Float: 123.456,
|
||||||
Float64: 1.2345678912345678e+17,
|
Float64: 1.2345678912345678e+17,
|
||||||
Bool: true,
|
Bool: true,
|
||||||
|
BoolRef: util.ToPtr(true),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Scan a different type with the same values to test that
|
// Scan a different type with the same values to test that
|
||||||
|
@ -167,6 +171,7 @@ var _ = Describe("Scan", func() {
|
||||||
Float: 1.0,
|
Float: 1.0,
|
||||||
Float64: 1.2345678912345678e+17,
|
Float64: 1.2345678912345678e+17,
|
||||||
Bool: true,
|
Bool: true,
|
||||||
|
BoolRef: util.ToPtr(true),
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,11 @@ func newStructSpec(t reflect.Type, fieldTag string) *structSpec {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the built-in decoder.
|
// Use the built-in decoder.
|
||||||
out.set(tag, &structField{index: i, fn: decoders[f.Type.Kind()]})
|
kind := f.Type.Kind()
|
||||||
|
if kind == reflect.Pointer {
|
||||||
|
kind = f.Type.Elem().Kind()
|
||||||
|
}
|
||||||
|
out.set(tag, &structField{index: i, fn: decoders[kind]})
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
9
json.go
9
json.go
|
@ -66,7 +66,6 @@ type JSONCmd struct {
|
||||||
var _ Cmder = (*JSONCmd)(nil)
|
var _ Cmder = (*JSONCmd)(nil)
|
||||||
|
|
||||||
func newJSONCmd(ctx context.Context, args ...interface{}) *JSONCmd {
|
func newJSONCmd(ctx context.Context, args ...interface{}) *JSONCmd {
|
||||||
|
|
||||||
return &JSONCmd{
|
return &JSONCmd{
|
||||||
baseCmd: baseCmd{
|
baseCmd: baseCmd{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
@ -95,7 +94,6 @@ func (cmd *JSONCmd) Val() string {
|
||||||
} else {
|
} else {
|
||||||
return cmd.val
|
return cmd.val
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *JSONCmd) Result() (string, error) {
|
func (cmd *JSONCmd) Result() (string, error) {
|
||||||
|
@ -103,7 +101,6 @@ func (cmd *JSONCmd) Result() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd JSONCmd) Expanded() (interface{}, error) {
|
func (cmd JSONCmd) Expanded() (interface{}, error) {
|
||||||
|
|
||||||
if len(cmd.val) != 0 && cmd.expanded == nil {
|
if len(cmd.val) != 0 && cmd.expanded == nil {
|
||||||
err := json.Unmarshal([]byte(cmd.val), &cmd.expanded)
|
err := json.Unmarshal([]byte(cmd.val), &cmd.expanded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -115,7 +112,6 @@ func (cmd JSONCmd) Expanded() (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *JSONCmd) readReply(rd *proto.Reader) error {
|
func (cmd *JSONCmd) readReply(rd *proto.Reader) error {
|
||||||
|
|
||||||
// nil response from JSON.(M)GET (cmd.baseCmd.err will be "redis: nil")
|
// nil response from JSON.(M)GET (cmd.baseCmd.err will be "redis: nil")
|
||||||
if cmd.baseCmd.Err() == Nil {
|
if cmd.baseCmd.Err() == Nil {
|
||||||
cmd.val = ""
|
cmd.val = ""
|
||||||
|
@ -131,7 +127,7 @@ func (cmd *JSONCmd) readReply(rd *proto.Reader) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var expanded = make([]interface{}, size)
|
expanded := make([]interface{}, size)
|
||||||
|
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
if expanded[i], err = rd.ReadReply(); err != nil {
|
if expanded[i], err = rd.ReadReply(); err != nil {
|
||||||
|
@ -186,7 +182,6 @@ func (cmd *JSONSliceCmd) Result() ([]interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *JSONSliceCmd) readReply(rd *proto.Reader) error {
|
func (cmd *JSONSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
|
|
||||||
if cmd.baseCmd.Err() == Nil {
|
if cmd.baseCmd.Err() == Nil {
|
||||||
cmd.val = nil
|
cmd.val = nil
|
||||||
return Nil
|
return Nil
|
||||||
|
@ -220,7 +215,6 @@ func (cmd *JSONSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -262,7 +256,6 @@ func (cmd *IntPointerSliceCmd) Result() ([]*int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *IntPointerSliceCmd) readReply(rd *proto.Reader) error {
|
func (cmd *IntPointerSliceCmd) readReply(rd *proto.Reader) error {
|
||||||
|
|
||||||
n, err := rd.ReadArrayLen()
|
n, err := rd.ReadArrayLen()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
11
json_test.go
11
json_test.go
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
. "github.com/bsm/ginkgo/v2"
|
. "github.com/bsm/ginkgo/v2"
|
||||||
. "github.com/bsm/gomega"
|
. "github.com/bsm/gomega"
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,7 +14,6 @@ type JSONGetTestStruct struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("JSON Commands", Label("json"), func() {
|
var _ = Describe("JSON Commands", Label("json"), func() {
|
||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
var client *redis.Client
|
var client *redis.Client
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ var _ = Describe("JSON Commands", Label("json"), func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("arrays", Label("arrays"), func() {
|
Describe("arrays", Label("arrays"), func() {
|
||||||
|
|
||||||
It("should JSONArrAppend", Label("json.arrappend", "json"), func() {
|
It("should JSONArrAppend", Label("json.arrappend", "json"), func() {
|
||||||
cmd1 := client.JSONSet(ctx, "append2", "$", `{"a": [10], "b": {"a": [12, 13]}}`)
|
cmd1 := client.JSONSet(ctx, "append2", "$", `{"a": [10], "b": {"a": [12, 13]}}`)
|
||||||
Expect(cmd1.Err()).NotTo(HaveOccurred())
|
Expect(cmd1.Err()).NotTo(HaveOccurred())
|
||||||
|
@ -76,7 +75,6 @@ var _ = Describe("JSON Commands", Label("json"), func() {
|
||||||
res, err = client.JSONArrIndexWithArgs(ctx, "index2", "$", &redis.JSONArrIndexArgs{Stop: &stop}, 4).Result()
|
res, err = client.JSONArrIndexWithArgs(ctx, "index2", "$", &redis.JSONArrIndexArgs{Stop: &stop}, 4).Result()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(res[0]).To(Equal(int64(-1)))
|
Expect(res[0]).To(Equal(int64(-1)))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should JSONArrIndex and JSONArrIndexWithArgs with $", Label("json.arrindex", "json"), func() {
|
It("should JSONArrIndex and JSONArrIndexWithArgs with $", Label("json.arrindex", "json"), func() {
|
||||||
|
@ -235,7 +233,6 @@ var _ = Describe("JSON Commands", Label("json"), func() {
|
||||||
Expect(cmd3.Err()).NotTo(HaveOccurred())
|
Expect(cmd3.Err()).NotTo(HaveOccurred())
|
||||||
Expect(cmd3.Val()).To(Equal("[[100,200,200]]"))
|
Expect(cmd3.Val()).To(Equal("[[100,200,200]]"))
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("get/set", Label("getset"), func() {
|
Describe("get/set", Label("getset"), func() {
|
||||||
|
@ -257,7 +254,6 @@ var _ = Describe("JSON Commands", Label("json"), func() {
|
||||||
res, err = client.JSONGetWithArgs(ctx, "get3", &redis.JSONGetArgs{Indent: "-", Newline: `~`, Space: `!`}).Result()
|
res, err = client.JSONGetWithArgs(ctx, "get3", &redis.JSONGetArgs{Indent: "-", Newline: `~`, Space: `!`}).Result()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(res).To(Equal(`[~-{~--"a":!1,~--"b":!2~-}~]`))
|
Expect(res).To(Equal(`[~-{~--"a":!1,~--"b":!2~-}~]`))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should JSONMerge", Label("json.merge", "json"), func() {
|
It("should JSONMerge", Label("json.merge", "json"), func() {
|
||||||
|
@ -330,13 +326,10 @@ var _ = Describe("JSON Commands", Label("json"), func() {
|
||||||
iRes, err = client.JSONMGet(ctx, "$..a", "non_existing_doc", "non_existing_doc1").Result()
|
iRes, err = client.JSONMGet(ctx, "$..a", "non_existing_doc", "non_existing_doc1").Result()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(iRes).To(Equal([]interface{}{nil, nil}))
|
Expect(iRes).To(Equal([]interface{}{nil, nil}))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("Misc", Label("misc"), func() {
|
Describe("Misc", Label("misc"), func() {
|
||||||
|
|
||||||
It("should JSONClear", Label("json.clear", "json"), func() {
|
It("should JSONClear", Label("json.clear", "json"), func() {
|
||||||
cmd1 := client.JSONSet(ctx, "clear1", "$", `[1]`)
|
cmd1 := client.JSONSet(ctx, "clear1", "$", `[1]`)
|
||||||
Expect(cmd1.Err()).NotTo(HaveOccurred())
|
Expect(cmd1.Err()).NotTo(HaveOccurred())
|
||||||
|
@ -460,7 +453,6 @@ var _ = Describe("JSON Commands", Label("json"), func() {
|
||||||
cmd3 := client.JSONGet(ctx, "forget3", "$")
|
cmd3 := client.JSONGet(ctx, "forget3", "$")
|
||||||
Expect(cmd3.Err()).NotTo(HaveOccurred())
|
Expect(cmd3.Err()).NotTo(HaveOccurred())
|
||||||
Expect(cmd3.Val()).To(Equal(`[{"b":{"b":"annie"}}]`))
|
Expect(cmd3.Val()).To(Equal(`[{"b":{"b":"annie"}}]`))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should JSONForget with $", Label("json.forget", "json"), func() {
|
It("should JSONForget with $", Label("json.forget", "json"), func() {
|
||||||
|
@ -622,7 +614,6 @@ var _ = Describe("JSON Commands", Label("json"), func() {
|
||||||
cmd3, err := client.JSONGet(ctx, "strapp1", "$").Result()
|
cmd3, err := client.JSONGet(ctx, "strapp1", "$").Result()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(cmd3).To(Equal(`["foobar"]`))
|
Expect(cmd3).To(Equal(`["foobar"]`))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should JSONStrAppend and JSONStrLen with $", Label("json.strappend", "json.strlen", "json"), func() {
|
It("should JSONStrAppend and JSONStrLen with $", Label("json.strappend", "json.strlen", "json"), func() {
|
||||||
|
|
Loading…
Reference in New Issue