Ver código fonte

feat: Add ptr support for scan and flatten

Add support to scan to a ptr and flatten from a ptr.
Yuchi W 6 anos atrás
pai
commit
4f569a4708
2 arquivos alterados com 43 adições e 28 exclusões
  1. 9 1
      redis/scan.go
  2. 34 27
      redis/scan_test.go

+ 9 - 1
redis/scan.go

@@ -99,6 +99,8 @@ func convertAssignString(d reflect.Value, s string) (err error) {
 		} else {
 		} else {
 			err = cannotConvert(d, s)
 			err = cannotConvert(d, s)
 		}
 		}
+	case reflect.Ptr:
+		err = convertAssignString(d.Elem(), s)
 	default:
 	default:
 		err = cannotConvert(d, s)
 		err = cannotConvert(d, s)
 	}
 	}
@@ -644,7 +646,13 @@ func flattenStruct(args Args, v reflect.Value) Args {
 				continue
 				continue
 			}
 			}
 		}
 		}
-		args = append(args, fs.name, fv.Interface())
+		if fv.Kind() == reflect.Ptr {
+			if !fv.IsNil() {
+				args = append(args, fs.name, fv.Elem().Interface())
+			}
+		} else {
+			args = append(args, fs.name, fv.Interface())
+		}
 	}
 	}
 	return args
 	return args
 }
 }

+ 34 - 27
redis/scan_test.go

@@ -201,19 +201,22 @@ type s0 struct {
 }
 }
 
 
 type s1 struct {
 type s1 struct {
-	X  int    `redis:"-"`
-	I  int    `redis:"i"`
-	U  uint   `redis:"u"`
-	S  string `redis:"s"`
-	P  []byte `redis:"p"`
-	B  bool   `redis:"b"`
-	Bt bool
-	Bf bool
+	X    int    `redis:"-"`
+	I    int    `redis:"i"`
+	U    uint   `redis:"u"`
+	S    string `redis:"s"`
+	P    []byte `redis:"p"`
+	B    bool   `redis:"b"`
+	Bt   bool
+	Bf   bool
+	PtrB *bool
 	s0
 	s0
 	Sd  durationScan  `redis:"sd"`
 	Sd  durationScan  `redis:"sd"`
 	Sdp *durationScan `redis:"sdp"`
 	Sdp *durationScan `redis:"sdp"`
 }
 }
 
 
+var boolTrue = true
+
 var scanStructTests = []struct {
 var scanStructTests = []struct {
 	title string
 	title string
 	reply []string
 	reply []string
@@ -228,22 +231,24 @@ var scanStructTests = []struct {
 			"b", "t",
 			"b", "t",
 			"Bt", "1",
 			"Bt", "1",
 			"Bf", "0",
 			"Bf", "0",
+			"PtrB", "1",
 			"X", "123",
 			"X", "123",
 			"y", "456",
 			"y", "456",
 			"sd", "1m",
 			"sd", "1m",
 			"sdp", "1m",
 			"sdp", "1m",
 		},
 		},
 		&s1{
 		&s1{
-			I:   -1234,
-			U:   5678,
-			S:   "hello",
-			P:   []byte("world"),
-			B:   true,
-			Bt:  true,
-			Bf:  false,
-			s0:  s0{X: 123, Y: 456},
-			Sd:  durationScan{Duration: time.Minute},
-			Sdp: &durationScan{Duration: time.Minute},
+			I:    -1234,
+			U:    5678,
+			S:    "hello",
+			P:    []byte("world"),
+			B:    true,
+			Bt:   true,
+			Bf:   false,
+			PtrB: &boolTrue,
+			s0:   s0{X: 123, Y: 456},
+			Sd:   durationScan{Duration: time.Minute},
+			Sdp:  &durationScan{Duration: time.Minute},
 		},
 		},
 	},
 	},
 	{"absent values",
 	{"absent values",
@@ -421,17 +426,19 @@ var argsTests = []struct {
 }{
 }{
 	{"struct ptr",
 	{"struct ptr",
 		redis.Args{}.AddFlat(&struct {
 		redis.Args{}.AddFlat(&struct {
-			I  int               `redis:"i"`
-			U  uint              `redis:"u"`
-			S  string            `redis:"s"`
-			P  []byte            `redis:"p"`
-			M  map[string]string `redis:"m"`
-			Bt bool
-			Bf bool
+			I    int               `redis:"i"`
+			U    uint              `redis:"u"`
+			S    string            `redis:"s"`
+			P    []byte            `redis:"p"`
+			M    map[string]string `redis:"m"`
+			Bt   bool
+			Bf   bool
+			PtrB *bool
+			PtrI *int
 		}{
 		}{
-			-1234, 5678, "hello", []byte("world"), map[string]string{"hello": "world"}, true, false,
+			-1234, 5678, "hello", []byte("world"), map[string]string{"hello": "world"}, true, false, &boolTrue, nil,
 		}),
 		}),
-		redis.Args{"i", int(-1234), "u", uint(5678), "s", "hello", "p", []byte("world"), "m", map[string]string{"hello": "world"}, "Bt", true, "Bf", false},
+		redis.Args{"i", int(-1234), "u", uint(5678), "s", "hello", "p", []byte("world"), "m", map[string]string{"hello": "world"}, "Bt", true, "Bf", false, "PtrB", true},
 	},
 	},
 	{"struct",
 	{"struct",
 		redis.Args{}.AddFlat(struct{ I int }{123}),
 		redis.Args{}.AddFlat(struct{ I int }{123}),