@@ -2659,7 +2659,6 @@ var _ = Describe("Commands", func() {
2659
2659
Expect (res ).To (Equal ([]int64 {1 , 1 , - 2 }))
2660
2660
})
2661
2661
2662
-
2663
2662
It ("should HPExpire" , Label ("hash-expiration" , "NonRedisEnterprise" ), func () {
2664
2663
SkipBeforeRedisVersion (7.4 , "doesn't work with older redis stack images" )
2665
2664
res , err := client .HPExpire (ctx , "no_such_key" , 10 * time .Second , "field1" , "field2" , "field3" ).Result ()
@@ -2812,6 +2811,155 @@ var _ = Describe("Commands", func() {
2812
2811
Expect (err ).NotTo (HaveOccurred ())
2813
2812
Expect (res [0 ]).To (BeNumerically ("~" , 10 * time .Second .Milliseconds (), 1 ))
2814
2813
})
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
+ })
2815
2963
})
2816
2964
2817
2965
Describe ("hyperloglog" , func () {
0 commit comments