@@ -2659,7 +2659,6 @@ var _ = Describe("Commands", func() {
26592659 Expect (res ).To (Equal ([]int64 {1 , 1 , - 2 }))
26602660 })
26612661
2662-
26632662 It ("should HPExpire" , Label ("hash-expiration" , "NonRedisEnterprise" ), func () {
26642663 SkipBeforeRedisVersion (7.4 , "doesn't work with older redis stack images" )
26652664 res , err := client .HPExpire (ctx , "no_such_key" , 10 * time .Second , "field1" , "field2" , "field3" ).Result ()
@@ -2812,6 +2811,155 @@ var _ = Describe("Commands", func() {
28122811 Expect (err ).NotTo (HaveOccurred ())
28132812 Expect (res [0 ]).To (BeNumerically ("~" , 10 * time .Second .Milliseconds (), 1 ))
28142813 })
2814+
2815+ It ("should HGETDEL" , Label ("hash" , "HGETDEL" ), func () {
2816+ SkipBeforeRedisVersion (7.9 , "requires Redis 8.x" )
2817+ // Setup: create a hash with three fields.
2818+ err := client .HSet (ctx , "myhash" , "f1" , "val1" , "f2" , "val2" , "f3" , "val3" ).Err ()
2819+ Expect (err ).NotTo (HaveOccurred ())
2820+
2821+ // Execute HGETDEL on fields f1 and f2.
2822+ res , err := client .HGetDel (ctx , "myhash" , "f1" , "f2" ).Result ()
2823+ Expect (err ).NotTo (HaveOccurred ())
2824+ // Expect the returned values for f1 and f2.
2825+ Expect (res ).To (Equal ([]string {"val1" , "val2" }))
2826+
2827+ // Verify that f1 and f2 have been deleted, while f3 remains.
2828+ remaining , err := client .HMGet (ctx , "myhash" , "f1" , "f2" , "f3" ).Result ()
2829+ Expect (err ).NotTo (HaveOccurred ())
2830+ Expect (remaining [0 ]).To (BeNil ())
2831+ Expect (remaining [1 ]).To (BeNil ())
2832+ Expect (remaining [2 ]).To (Equal ("val3" ))
2833+ })
2834+
2835+ It ("should return nil responses for HGETDEL on non-existent key" , Label ("hash" , "HGETDEL" ), func () {
2836+ SkipBeforeRedisVersion (7.9 , "requires Redis 8.x" )
2837+ // HGETDEL on a key that does not exist.
2838+ res , err := client .HGetDel (ctx , "nonexistent" , "f1" , "f2" ).Result ()
2839+ Expect (err ).To (BeNil ())
2840+ // Depending on your implementation, missing fields may return nil or empty strings.
2841+ // Adjust the expectation accordingly.
2842+ Expect (res ).To (Equal ([]string {"" , "" }))
2843+ })
2844+
2845+ // -----------------------------
2846+ // HGETEX with various TTL options
2847+ // -----------------------------
2848+ It ("should HGETEX with EX option" , Label ("hash" , "HGETEX" ), func () {
2849+ SkipBeforeRedisVersion (7.9 , "requires Redis 8.x" )
2850+ // Setup: create a hash.
2851+ err := client .HSet (ctx , "myhash" , "f1" , "val1" , "f2" , "val2" ).Err ()
2852+ Expect (err ).NotTo (HaveOccurred ())
2853+
2854+ // Call HGETEX with EX option and 60 seconds TTL.
2855+ res , err := client .HGetEXWithArgs (ctx , "myhash" , redis .HGetEXExpirationEX , 60 , "f1" , "f2" ).Result ()
2856+ Expect (err ).NotTo (HaveOccurred ())
2857+ Expect (res ).To (Equal ([]string {"val1" , "val2" }))
2858+ // Optionally, verify TTL if your implementation exposes it.
2859+ })
2860+
2861+ It ("should HGETEX with PERSIST option" , Label ("hash" , "HGETEX" ), func () {
2862+ SkipBeforeRedisVersion (8 , "requires Redis 8.x" )
2863+ // Setup: create a hash.
2864+ err := client .HSet (ctx , "myhash" , "f1" , "val1" , "f2" , "val2" ).Err ()
2865+ Expect (err ).NotTo (HaveOccurred ())
2866+
2867+ // Call HGETEX with PERSIST (no TTL value needed).
2868+ res , err := client .HGetEXWithArgs (ctx , "myhash" , redis .HGetEXExpirationPERSIST , 0 , "f1" , "f2" ).Result ()
2869+ Expect (err ).NotTo (HaveOccurred ())
2870+ Expect (res ).To (Equal ([]string {"val1" , "val2" }))
2871+ })
2872+
2873+ It ("should HGETEX with EXAT option" , Label ("hash" , "HGETEX" ), func () {
2874+ SkipBeforeRedisVersion (8 , "requires Redis 8.x" )
2875+ // Setup: create a hash.
2876+ err := client .HSet (ctx , "myhash" , "f1" , "val1" , "f2" , "val2" ).Err ()
2877+ Expect (err ).NotTo (HaveOccurred ())
2878+
2879+ // Set expiration at a specific Unix timestamp (60 seconds from now).
2880+ expireAt := time .Now ().Add (60 * time .Second ).Unix ()
2881+ res , err := client .HGetEXWithArgs (ctx , "myhash" , redis .HGetEXExpirationEXAT , expireAt , "f1" , "f2" ).Result ()
2882+ Expect (err ).NotTo (HaveOccurred ())
2883+ Expect (res ).To (Equal ([]string {"val1" , "val2" }))
2884+ })
2885+
2886+ // -----------------------------
2887+ // HSETEX with FNX/FXX options
2888+ // -----------------------------
2889+ It ("should HSETEX with FNX condition" , Label ("hash" , "HSETEX" ), func () {
2890+ SkipBeforeRedisVersion (8 , "requires Redis 8.x" )
2891+ // Ensure the key is removed.
2892+ client .Del (ctx , "myhash" )
2893+
2894+ // FNX: set field only if it does not exist.
2895+ opt := redis.HSetXOptions {
2896+ Condition : redis .HSetEXFNX ,
2897+ ExpirationType : redis .HSetEXExpirationEX ,
2898+ ExpirationVal : 60 ,
2899+ }
2900+ res , err := client .HSetEXWithArgs (ctx , "myhash" , & opt , "f1" , "val1" ).Result ()
2901+ Expect (err ).NotTo (HaveOccurred ())
2902+ // Expect the field to be set.
2903+ Expect (res ).To (Equal (int64 (1 )))
2904+
2905+ opt = redis.HSetXOptions {
2906+ Condition : redis .HSetEXFNX ,
2907+ ExpirationType : redis .HSetEXExpirationEX ,
2908+ ExpirationVal : 60 ,
2909+ }
2910+ // Attempt to set the same field again with FNX.
2911+ res , err = client .HSetEXWithArgs (ctx , "myhash" , & opt , "f1" , "val2" ).Result ()
2912+ Expect (err ).NotTo (HaveOccurred ())
2913+ // Since the field already exists, no update occurs.
2914+ Expect (res ).To (Equal (int64 (0 )))
2915+ })
2916+
2917+ It ("should HSETEX with FXX condition" , Label ("hash" , "HSETEX" ), func () {
2918+ SkipBeforeRedisVersion (7.9 , "requires Redis 8.x" )
2919+ // Setup: ensure field f2 exists.
2920+ client .Del (ctx , "myhash" )
2921+ err := client .HSet (ctx , "myhash" , "f2" , "val1" ).Err ()
2922+ Expect (err ).NotTo (HaveOccurred ())
2923+
2924+ opt := redis.HSetXOptions {
2925+ Condition : redis .HSetEXFXX ,
2926+ ExpirationType : redis .HSetEXExpirationEX ,
2927+ ExpirationVal : 60 ,
2928+ }
2929+ // FXX: update field only if it exists.
2930+ res , err := client .HSetEXWithArgs (ctx , "myhash" , & opt , "f2" , "val2" ).Result ()
2931+ Expect (err ).NotTo (HaveOccurred ())
2932+ Expect (res ).To (Equal (int64 (1 )))
2933+ opt = redis.HSetXOptions {
2934+ Condition : redis .HSetEXFXX ,
2935+ ExpirationType : redis .HSetEXExpirationEX ,
2936+ ExpirationVal : 60 ,
2937+ }
2938+ // FXX on a non-existing field (f3) should not set the field.
2939+ res , err = client .HSetEXWithArgs (ctx , "myhash" , & opt , "f3" , "val3" ).Result ()
2940+ Expect (err ).NotTo (HaveOccurred ())
2941+ Expect (res ).To (Equal (int64 (0 )))
2942+ })
2943+
2944+ It ("should HSETEX with multiple field operations" , Label ("hash" , "HSETEX" ), func () {
2945+ SkipBeforeRedisVersion (8 , "requires Redis 8.x" )
2946+ // Remove key if it exists.
2947+ client .Del (ctx , "myhash" )
2948+ opt := redis.HSetXOptions {
2949+ ExpirationType : redis .HSetEXExpirationEX ,
2950+ ExpirationVal : 60 ,
2951+ }
2952+ // Set multiple fields at once (no condition).
2953+ res , err := client .HSetEXWithArgs (ctx , "myhash" , & opt , "f1" , "val1" , "f2" , "val2" ).Result ()
2954+ Expect (err ).NotTo (HaveOccurred ())
2955+ // Assume 1 indicates all fields were set.
2956+ Expect (res ).To (Equal (int64 (1 )))
2957+
2958+ // Verify that both fields are set.
2959+ values , err := client .HMGet (ctx , "myhash" , "f1" , "f2" ).Result ()
2960+ Expect (err ).NotTo (HaveOccurred ())
2961+ Expect (values ).To (Equal ([]interface {}{"val1" , "val2" }))
2962+ })
28152963 })
28162964
28172965 Describe ("hyperloglog" , func () {
0 commit comments