|  | 
|  | 1 | +package main | 
|  | 2 | + | 
|  | 3 | +import ( | 
|  | 4 | +	"context" | 
|  | 5 | +	"time" | 
|  | 6 | + | 
|  | 7 | +	"github.com/davecgh/go-spew/spew" | 
|  | 8 | + | 
|  | 9 | +	"github.com/redis/go-redis/v9" | 
|  | 10 | +) | 
|  | 11 | + | 
|  | 12 | +type Model struct { | 
|  | 13 | +	Str1    string     `redis:"str1"` | 
|  | 14 | +	Str2    string     `redis:"str2"` | 
|  | 15 | +	Str3    *string    `redis:"str3"` | 
|  | 16 | +	Str4    *string    `redis:"str4"` | 
|  | 17 | +	Bytes   []byte     `redis:"bytes"` | 
|  | 18 | +	Int     int        `redis:"int"` | 
|  | 19 | +	Int2    *int       `redis:"int2"` | 
|  | 20 | +	Int3    *int       `redis:"int3"` | 
|  | 21 | +	Bool    bool       `redis:"bool"` | 
|  | 22 | +	Bool2   *bool      `redis:"bool2"` | 
|  | 23 | +	Bool3   *bool      `redis:"bool3"` | 
|  | 24 | +	Bool4   *bool      `redis:"bool4,omitempty"` | 
|  | 25 | +	Time    time.Time  `redis:"time"` | 
|  | 26 | +	Time2   *time.Time `redis:"time2"` | 
|  | 27 | +	Time3   *time.Time `redis:"time3"` | 
|  | 28 | +	Ignored struct{}   `redis:"-"` | 
|  | 29 | +} | 
|  | 30 | + | 
|  | 31 | +func main() { | 
|  | 32 | +	ctx := context.Background() | 
|  | 33 | + | 
|  | 34 | +	rdb := redis.NewClient(&redis.Options{ | 
|  | 35 | +		Addr: ":6379", | 
|  | 36 | +	}) | 
|  | 37 | + | 
|  | 38 | +	_ = rdb.FlushDB(ctx).Err() | 
|  | 39 | + | 
|  | 40 | +	t := time.Date(2025, 02, 8, 0, 0, 0, 0, time.UTC) | 
|  | 41 | + | 
|  | 42 | +	data := Model{ | 
|  | 43 | +		Str1:    "hello", | 
|  | 44 | +		Str2:    "world", | 
|  | 45 | +		Str3:    ToPtr("hello"), | 
|  | 46 | +		Str4:    nil, | 
|  | 47 | +		Bytes:   []byte("this is bytes !"), | 
|  | 48 | +		Int:     123, | 
|  | 49 | +		Int2:    ToPtr(0), | 
|  | 50 | +		Int3:    nil, | 
|  | 51 | +		Bool:    true, | 
|  | 52 | +		Bool2:   ToPtr(false), | 
|  | 53 | +		Bool3:   nil, | 
|  | 54 | +		Time:    t, | 
|  | 55 | +		Time2:   ToPtr(t), | 
|  | 56 | +		Time3:   nil, | 
|  | 57 | +		Ignored: struct{}{}, | 
|  | 58 | +	} | 
|  | 59 | + | 
|  | 60 | +	// Set some fields. | 
|  | 61 | +	if _, err := rdb.Pipelined(ctx, func(rdb redis.Pipeliner) error { | 
|  | 62 | +		rdb.HMSet(ctx, "key", data) | 
|  | 63 | +		return nil | 
|  | 64 | +	}); err != nil { | 
|  | 65 | +		panic(err) | 
|  | 66 | +	} | 
|  | 67 | + | 
|  | 68 | +	var model1, model2 Model | 
|  | 69 | + | 
|  | 70 | +	// Scan all fields into the model. | 
|  | 71 | +	if err := rdb.HGetAll(ctx, "key").Scan(&model1); err != nil { | 
|  | 72 | +		panic(err) | 
|  | 73 | +	} | 
|  | 74 | + | 
|  | 75 | +	// Or scan a subset of the fields. | 
|  | 76 | +	if err := rdb.HMGet(ctx, "key", "str1", "int").Scan(&model2); err != nil { | 
|  | 77 | +		panic(err) | 
|  | 78 | +	} | 
|  | 79 | + | 
|  | 80 | +	spew.Dump(model1) | 
|  | 81 | +	// Output: | 
|  | 82 | +	// (main.Model) { | 
|  | 83 | +	//  Str1: (string) (len=5) "hello", | 
|  | 84 | +	//  Str2: (string) (len=5) "world", | 
|  | 85 | +	//  Str3: (*string)(0xc000016970)((len=5) "hello"), | 
|  | 86 | +	//  Str4: (*string)(0xc000016980)(""), | 
|  | 87 | +	//  Bytes: ([]uint8) (len=15 cap=16) { | 
|  | 88 | +	//   00000000  74 68 69 73 20 69 73 20  62 79 74 65 73 20 21     |this is bytes !| | 
|  | 89 | +	//  }, | 
|  | 90 | +	//  Int: (int) 123, | 
|  | 91 | +	//  Int2: (*int)(0xc000014568)(0), | 
|  | 92 | +	//  Int3: (*int)(0xc000014560)(0), | 
|  | 93 | +	//  Bool: (bool) true, | 
|  | 94 | +	//  Bool2: (*bool)(0xc000014570)(false), | 
|  | 95 | +	//  Bool3: (*bool)(0xc000014548)(false), | 
|  | 96 | +	//  Bool4: (*bool)(<nil>), | 
|  | 97 | +	//  Time: (time.Time) 2025-02-08 00:00:00 +0000 UTC, | 
|  | 98 | +	//  Time2: (*time.Time)(0xc0000122a0)(2025-02-08 00:00:00 +0000 UTC), | 
|  | 99 | +	//  Time3: (*time.Time)(0xc000012288)(0001-01-01 00:00:00 +0000 UTC), | 
|  | 100 | +	//  Ignored: (struct {}) { | 
|  | 101 | +	//  } | 
|  | 102 | +	// } | 
|  | 103 | + | 
|  | 104 | +	spew.Dump(model2) | 
|  | 105 | +	// Output: | 
|  | 106 | +	// (main.Model) { | 
|  | 107 | +	//  Str1: (string) (len=5) "hello", | 
|  | 108 | +	//  Str2: (string) "", | 
|  | 109 | +	//  Str3: (*string)(<nil>), | 
|  | 110 | +	//  Str4: (*string)(<nil>), | 
|  | 111 | +	//  Bytes: ([]uint8) <nil>, | 
|  | 112 | +	//  Int: (int) 123, | 
|  | 113 | +	//  Int2: (*int)(<nil>), | 
|  | 114 | +	//  Int3: (*int)(<nil>), | 
|  | 115 | +	//  Bool: (bool) false, | 
|  | 116 | +	//  Bool2: (*bool)(<nil>), | 
|  | 117 | +	//  Bool3: (*bool)(<nil>), | 
|  | 118 | +	//  Bool4: (*bool)(<nil>), | 
|  | 119 | +	//  Time: (time.Time) 0001-01-01 00:00:00 +0000 UTC, | 
|  | 120 | +	//  Time2: (*time.Time)(<nil>), | 
|  | 121 | +	//  Time3: (*time.Time)(<nil>), | 
|  | 122 | +	//  Ignored: (struct {}) { | 
|  | 123 | +	//  } | 
|  | 124 | +	// } | 
|  | 125 | +} | 
|  | 126 | + | 
|  | 127 | +func ToPtr[T any](v T) *T { | 
|  | 128 | +	return &v | 
|  | 129 | +} | 
0 commit comments