Skip to content

Commit 4561d98

Browse files
DEV: add TCEs to HEXPIRE command page (#2253)
* DEV: add TCEs to HEXPIRE command page * Update local_examples/cmds_hash/lettuce-async/CmdsHashExample.java Co-authored-by: andy-stark-redis <[email protected]> * Apply code review suggestions * DOC-5633 fixed HashFieldExpire, etc --------- Co-authored-by: andy-stark-redis <[email protected]> Co-authored-by: Andy Stark <[email protected]>
1 parent a8b3a3e commit 4561d98

File tree

10 files changed

+450
-14
lines changed

10 files changed

+450
-14
lines changed

local_examples/cmds_hash/NRedisStack/CmdsHashExample.cs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// EXAMPLE: cmds_hash
22
using StackExchange.Redis;
33
using Xunit;
4+
using System.Linq;
45

56
namespace Doc;
67

@@ -22,12 +23,14 @@ public void Run()
2223

2324
RedisValue hdelRes3 = db.HashDelete("myhash", "field1");
2425
Console.WriteLine(hdelRes3); // >>> 0
25-
2626
// STEP_END
27+
28+
// REMOVE_START
2729
Assert.True(hdelRes1);
2830
Assert.Equal(1, hdelRes2);
2931
Assert.Equal(0, hdelRes3);
3032
db.KeyDelete("myhash");
33+
// REMOVE_END
3134

3235
// STEP_START hget
3336
bool hgetRes1 = db.HashSet("myhash", "field1", "foo");
@@ -37,12 +40,14 @@ public void Run()
3740

3841
RedisValue hgetRes3 = db.HashGet("myhash", "field2");
3942
Console.WriteLine(hgetRes3); // >>> Null
40-
4143
// STEP_END
44+
45+
// REMOVE_START
4246
Assert.True(hgetRes1);
4347
Assert.Equal("foo", hgetRes2);
4448
Assert.Equal(RedisValue.Null, hgetRes3);
4549
db.KeyDelete("myhash");
50+
// REMOVE_END
4651

4752
// STEP_START hset
4853
bool hsetRes1 = db.HashSet("myhash", "field1", "Hello");
@@ -66,8 +71,9 @@ public void Run()
6671
HashEntry[] hsetRes5 = db.HashGetAll("myhash");
6772
Console.WriteLine($"{string.Join(", ", hsetRes5.Select(h => $"{h.Name}: {h.Value}"))}");
6873
// >>> field1: Hello, field2: Hi, field3: World
69-
7074
// STEP_END
75+
76+
// REMOVE_START
7177
Assert.True(hsetRes1);
7278
Assert.Equal("Hello", hsetRes2);
7379
Assert.Equal("Hi", hsetRes3);
@@ -77,6 +83,7 @@ public void Run()
7783
string.Join(", ", hsetRes5.Select(h => $"{h.Name}: {h.Value}"))
7884
);
7985
db.KeyDelete("myhash");
86+
// REMOVE_END
8087

8188
// STEP_START hgetall
8289
db.HashSet("myhash",
@@ -93,8 +100,11 @@ public void Run()
93100
);
94101
// >>> field1: Hello, field2: World
95102
// STEP_END
103+
104+
// REMOVE_START
96105
Assert.Equal("field1: Hello, field2: World", string.Join(", ", hGetAllResult.Select(e => $"{e.Name}: {e.Value}")));
97106
db.KeyDelete("myhash");
107+
// REMOVE_END
98108

99109
// STEP_START hvals
100110
db.HashSet("myhash",
@@ -109,6 +119,51 @@ public void Run()
109119
Console.WriteLine(string.Join(", ", hValsResult));
110120
// >>> Hello, World
111121
// STEP_END
122+
123+
// REMOVE_START
112124
Assert.Equal("Hello, World", string.Join(", ", hValsResult));
125+
db.KeyDelete("myhash");
126+
// REMOVE_END
127+
128+
// STEP_START hexpire
129+
// Set up hash with fields
130+
db.HashSet("myhash",
131+
[
132+
new("field1", "Hello"),
133+
new("field2", "World")
134+
]
135+
);
136+
137+
ExpireResult[] hexpireRes1 = db.HashFieldExpire(
138+
"myhash",
139+
new RedisValue[] { "field1", "field2" },
140+
TimeSpan.FromSeconds(10)
141+
);
142+
Console.WriteLine(string.Join(", ", hexpireRes1));
143+
// >>> Success, Success
144+
145+
long[] hexpireRes2 = db.HashFieldGetTimeToLive(
146+
"myhash",
147+
new RedisValue[] { "field1", "field2" }
148+
);
149+
Console.WriteLine(string.Join(", ", hexpireRes2));
150+
// >>> 10, 10 (approximately)
151+
152+
// Try to set expiration on non-existent field
153+
ExpireResult[] hexpireRes3 = db.HashFieldExpire(
154+
"myhash",
155+
new RedisValue[] { "nonexistent" },
156+
TimeSpan.FromSeconds(10)
157+
);
158+
Console.WriteLine(string.Join(", ", hexpireRes3));
159+
// >>> NoSuchField
160+
// STEP_END
161+
// REMOVE_START
162+
Assert.Equal("Success, Success", string.Join(", ", hexpireRes1));
163+
Assert.Equal(2, hexpireRes2.Length);
164+
Assert.True(hexpireRes2.All(ttl => ttl > 0)); // TTL should be positive
165+
Assert.Equal("NoSuchField", string.Join(", ", hexpireRes3));
166+
db.KeyDelete("myhash");
167+
// REMOVE_END
113168
}
114169
}

local_examples/cmds_hash/go-redis/cmds_hash_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"context"
77
"fmt"
88
"sort"
9+
"time"
910

1011
"github.com/redis/go-redis/v9"
1112
)
@@ -293,4 +294,54 @@ func ExampleClient_hdel() {
293294
// 1
294295
// 1
295296
// 0
297+
}
298+
299+
func ExampleClient_hexpire() {
300+
ctx := context.Background()
301+
302+
rdb := redis.NewClient(&redis.Options{
303+
Addr: "localhost:6379",
304+
Password: "", // no password
305+
DB: 0, // use default DB
306+
})
307+
308+
// STEP_START hexpire
309+
// Set up hash with fields
310+
rdb.HSet(ctx, "myhash", "field1", "Hello", "field2", "World")
311+
312+
// Set expiration on hash fields
313+
res1, err := rdb.HExpire(ctx, "myhash", 10*time.Second, "field1", "field2").Result()
314+
315+
if err != nil {
316+
fmt.Println(err)
317+
}
318+
319+
fmt.Println(res1) // >>> [1 1]
320+
321+
// Check TTL of the fields
322+
res2, err := rdb.HTTL(ctx, "myhash", "field1", "field2").Result()
323+
324+
if err != nil {
325+
fmt.Println(err)
326+
}
327+
328+
fmt.Println(len(res2)) // >>> 2
329+
330+
// Try to set expiration on non-existent field
331+
res3, err := rdb.HExpire(ctx, "myhash", 10*time.Second, "nonexistent").Result()
332+
333+
if err != nil {
334+
fmt.Println(err)
335+
}
336+
337+
fmt.Println(res3) // >>> [-2]
338+
339+
// Clean up
340+
rdb.Del(ctx, "myhash")
341+
// STEP_END
342+
343+
// Output:
344+
// [1 1]
345+
// 2
346+
// [-2]
296347
}

local_examples/cmds_hash/jedis/CmdsHashExample.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.Map;
1010
import java.util.List;
1111
import java.util.Collections;
12+
import java.util.Arrays;
1213

1314
// HIDE_START
1415
import redis.clients.jedis.UnifiedJedis;
@@ -17,6 +18,7 @@
1718
import static java.util.stream.Collectors.toList;
1819
import static org.junit.jupiter.api.Assertions.assertEquals;
1920
import static org.junit.jupiter.api.Assertions.assertNull;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
2022

2123
// HIDE_START
2224
public class CmdsHashExample {
@@ -159,13 +161,41 @@ public void run() {
159161
System.out.println(hValsResult2);
160162
// >>> [Hello, World]
161163
// STEP_END
162-
// REMOVE_START
164+
// REMOVE_START
163165
// Tests for 'hvals' step.
164166
assertEquals(2, hValsResult1);
165167
assertEquals("[Hello, World]", hValsResult2.toString());
166168
jedis.del("myhash");
167169
// REMOVE_END
168170

171+
// STEP_START hexpire
172+
// Set up hash with fields
173+
Map<String, String> hExpireExampleParams = new HashMap<>();
174+
hExpireExampleParams.put("field1", "Hello");
175+
hExpireExampleParams.put("field2", "World");
176+
jedis.hset("myhash", hExpireExampleParams);
177+
178+
// Set expiration on hash fields
179+
List<Long> hExpireResult1 = jedis.hexpire("myhash", 10, "field1", "field2");
180+
System.out.println(hExpireResult1); // >>> [1, 1]
181+
182+
// Check TTL of the fields
183+
List<Long> hExpireResult2 = jedis.httl("myhash", "field1", "field2");
184+
System.out.println(hExpireResult2.size()); // >>> 2
185+
186+
// Try to set expiration on non-existent field
187+
List<Long> hExpireResult3 = jedis.hexpire("myhash", 10, "nonexistent");
188+
System.out.println(hExpireResult3); // >>> [-2]
189+
// STEP_END
190+
// REMOVE_START
191+
// Tests for 'hexpire' step.
192+
assertEquals(Arrays.asList(1L, 1L), hExpireResult1);
193+
assertEquals(2, hExpireResult2.size());
194+
assertTrue(hExpireResult2.stream().allMatch(ttl -> ttl > 0)); // TTL should be positive
195+
assertEquals(Arrays.asList(-2L), hExpireResult3);
196+
jedis.del("myhash");
197+
// REMOVE_END
198+
169199
// HIDE_START
170200
jedis.close();
171201
}

local_examples/cmds_hash/lettuce-async/CmdsHashExample.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,52 @@ public void run() {
184184
// REMOVE_START
185185
asyncCommands.del("myhash").toCompletableFuture().join();
186186
// REMOVE_END
187+
188+
// STEP_START hexpire
189+
// Set up hash with fields
190+
Map<String, String> hExpireExampleParams = new HashMap<>();
191+
hExpireExampleParams.put("field1", "Hello");
192+
hExpireExampleParams.put("field2", "World");
193+
194+
CompletableFuture<Void> hExpireExample = asyncCommands.hset("myhash", hExpireExampleParams).thenCompose(res1 -> {
195+
// REMOVE_START
196+
assertThat(res1).isEqualTo(2L);
197+
// REMOVE_END
198+
// Set expiration on hash fields
199+
return asyncCommands.hexpire("myhash", 10, "field1", "field2");
200+
}).thenCompose(res2 -> {
201+
System.out.println(res2);
202+
// >>> [1, 1]
203+
// REMOVE_START
204+
assertThat(res2).isEqualTo(Arrays.asList(1L, 1L));
205+
// REMOVE_END
206+
// Check TTL of the fields
207+
return asyncCommands.httl("myhash", "field1", "field2");
208+
}).thenCompose(res3 -> {
209+
System.out.println(res3.size());
210+
// >>> 2
211+
// REMOVE_START
212+
assertThat(res3.size()).isEqualTo(2);
213+
assertThat(res3.stream().allMatch(ttl -> ttl > 0)).isTrue(); // TTL should be positive
214+
// REMOVE_END
215+
// Try to set expiration on non-existent field
216+
return asyncCommands.hexpire("myhash", 10, "nonexistent");
217+
})
218+
// REMOVE_START
219+
.thenApply(res4 -> {
220+
assertThat(res4).isEqualTo(Arrays.asList(-2L));
221+
return res;
222+
})
223+
// REMOVE_END
224+
.thenAccept(System.out::println)
225+
// >>> -2
226+
.toCompletableFuture();
227+
// STEP_END
228+
229+
hExpireExample.join();
230+
// REMOVE_START
231+
asyncCommands.del("myhash").toCompletableFuture().join();
232+
// REMOVE_END
187233
} finally {
188234
redisClient.shutdown();
189235
}

local_examples/cmds_hash/lettuce-reactive/CmdsHashExample.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,58 @@ public void run() {
224224
// REMOVE_START
225225
reactiveCommands.del("myhash").block();
226226
// REMOVE_END
227+
228+
// STEP_START hexpire
229+
// Set up hash with fields
230+
Map<String, String> hExpireExampleParams = new HashMap<>();
231+
hExpireExampleParams.put("field1", "Hello");
232+
hExpireExampleParams.put("field2", "World");
233+
234+
Mono<Long> hExpireExample1 = reactiveCommands.hset("myhash", hExpireExampleParams).doOnNext(result -> {
235+
// REMOVE_START
236+
assertThat(result).isEqualTo(2L);
237+
// REMOVE_END
238+
});
239+
240+
hExpireExample1.block();
241+
242+
// Set expiration on hash fields
243+
Mono<List<Long>> hExpireExample2 = reactiveCommands.hexpire("myhash", 10, "field1", "field2").collectList().doOnNext(result -> {
244+
System.out.println(result);
245+
// >>> [1, 1]
246+
// REMOVE_START
247+
assertThat(result).isEqualTo(Arrays.asList(1L, 1L));
248+
// REMOVE_END
249+
});
250+
251+
hExpireExample2.block();
252+
253+
// Check TTL of the fields
254+
Mono<List<Long>> hExpireExample3 = reactiveCommands.httl("myhash", "field1", "field2").collectList().doOnNext(result -> {
255+
System.out.println(result.size());
256+
// >>> 2
257+
// REMOVE_START
258+
assertThat(result.size()).isEqualTo(2);
259+
assertThat(result.stream().allMatch(ttl -> ttl > 0)).isTrue(); // TTL should be positive
260+
// REMOVE_END
261+
});
262+
263+
hExpireExample3.block();
264+
265+
// Try to set expiration on non-existent field
266+
Mono<List<Long>> hExpireExample4 = reactiveCommands.hexpire("myhash", 10, "nonexistent").collectList().doOnNext(result -> {
267+
System.out.println(result);
268+
// >>> [-2]
269+
// REMOVE_START
270+
assertThat(result).isEqualTo(Arrays.asList(-2L));
271+
// REMOVE_END
272+
});
273+
// STEP_END
274+
275+
hExpireExample4.block();
276+
// REMOVE_START
277+
reactiveCommands.del("myhash").block();
278+
// REMOVE_END
227279
} finally {
228280
redisClient.shutdown();
229281
}

local_examples/cmds_hash/node-redis/cmds-hash.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,33 @@ await client.del('myhash')
122122
// REMOVE_END
123123
// STEP_END
124124

125+
// STEP_START hexpire
126+
// Set up hash with fields
127+
await client.hSet('myhash', {
128+
'field1': 'Hello',
129+
'field2': 'World'
130+
})
131+
132+
// Set expiration on hash fields
133+
const res14 = await client.hExpire('myhash', ['field1', 'field2'], 10)
134+
console.log(res14) // [1, 1]
135+
136+
// Check TTL of the fields
137+
const res15 = await client.hTTL('myhash', ['field1', 'field2'])
138+
console.log(res15) // [10, 10] (or close to 10)
139+
140+
// Try to set expiration on non-existent field
141+
const res16 = await client.hExpire('myhash', ['nonexistent'], 10)
142+
console.log(res16) // [-2]
143+
144+
// REMOVE_START
145+
assert.deepEqual(res14, [1, 1]);
146+
assert(res15.every(ttl => ttl > 0)); // TTL should be positive
147+
assert.deepEqual(res16, [-2]);
148+
await client.del('myhash')
149+
// REMOVE_END
150+
// STEP_END
151+
125152
// HIDE_START
126153
await client.close();
127154
// HIDE_END

0 commit comments

Comments
 (0)