Skip to content

Commit 04f111f

Browse files
committed
DEV: add TCEs to HEXPIRE command page
1 parent 4a2a34f commit 04f111f

File tree

10 files changed

+410
-1
lines changed

10 files changed

+410
-1
lines changed

local_examples/cmds_hash/NRedisStack/CmdsHashExample.cs

Lines changed: 36 additions & 0 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

@@ -110,5 +111,40 @@ public void Run()
110111
// >>> Hello, World
111112
// STEP_END
112113
Assert.Equal("Hello, World", string.Join(", ", hValsResult));
114+
db.KeyDelete("myhash");
115+
116+
// STEP_START hexpire
117+
// Set up hash with fields
118+
db.HashSet("myhash",
119+
[
120+
new("field1", "Hello"),
121+
new("field2", "World")
122+
]
123+
);
124+
125+
// Set expiration on hash fields using raw Execute
126+
RedisResult hexpireRes1 = db.Execute("HEXPIRE", "myhash", 10, "FIELDS", 2, "field1", "field2");
127+
Console.WriteLine(string.Join(", ", (RedisValue[])hexpireRes1));
128+
// >>> 1, 1
129+
130+
// Check TTL of the fields using raw Execute
131+
RedisResult hexpireRes2 = db.Execute("HTTL", "myhash", "FIELDS", 2, "field1", "field2");
132+
RedisValue[] ttlValues = (RedisValue[])hexpireRes2;
133+
Console.WriteLine(ttlValues.Length);
134+
// >>> 2
135+
136+
// Try to set expiration on non-existent field
137+
RedisResult hexpireRes3 = db.Execute("HEXPIRE", "myhash", 10, "FIELDS", 1, "nonexistent");
138+
Console.WriteLine(string.Join(", ", (RedisValue[])hexpireRes3));
139+
// >>> -2
140+
// STEP_END
141+
142+
RedisValue[] expireResult1 = (RedisValue[])hexpireRes1;
143+
RedisValue[] expireResult3 = (RedisValue[])hexpireRes3;
144+
Assert.Equal("1, 1", string.Join(", ", expireResult1));
145+
Assert.Equal(2, ttlValues.Length);
146+
Assert.True(ttlValues.All(ttl => (int)ttl > 0)); // TTL should be positive
147+
Assert.Equal("-2", string.Join(", ", expireResult3));
148+
db.KeyDelete("myhash");
113149
}
114150
}

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: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,49 @@ 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+
}).thenAccept(res4 -> {
218+
System.out.println(res4);
219+
// >>> [-2]
220+
// REMOVE_START
221+
assertThat(res4).isEqualTo(Arrays.asList(-2L));
222+
// REMOVE_END
223+
}).toCompletableFuture();
224+
// STEP_END
225+
226+
hExpireExample.join();
227+
// REMOVE_START
228+
asyncCommands.del("myhash").toCompletableFuture().join();
229+
// REMOVE_END
187230
} finally {
188231
redisClient.shutdown();
189232
}

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

local_examples/cmds_hash/predis/CmdsHashTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,34 @@ public function testCmdsHash(): void
122122
$this->assertEquals('OK', $hValsResult1);
123123
$this->assertEquals(['Hello', 'World'], $hValsResult2);
124124

125+
// STEP_START hexpire
126+
echo "\n--- HEXPIRE Command ---\n";
127+
// Clean up first
128+
$this->redis->del('myhash');
129+
130+
// Set up hash with fields
131+
$hExpireResult1 = $this->redis->hmset('myhash', ['field1' => 'Hello', 'field2' => 'World']);
132+
echo "HMSET myhash field1 Hello field2 World: " . ($hExpireResult1 ? 'OK' : 'FAIL') . "\n"; // >>> OK
133+
134+
// Set expiration on hash fields
135+
$hExpireResult2 = $this->redis->hexpire('myhash', 10, ['field1', 'field2']);
136+
echo "HEXPIRE myhash 10 FIELDS field1 field2: " . json_encode($hExpireResult2) . "\n"; // >>> [1,1]
137+
138+
// Check TTL of the fields
139+
$hExpireResult3 = $this->redis->httl('myhash', ['field1', 'field2']);
140+
echo "HTTL myhash FIELDS field1 field2 count: " . count($hExpireResult3) . "\n"; // >>> 2
141+
142+
// Try to set expiration on non-existent field
143+
$hExpireResult4 = $this->redis->hexpire('myhash', 10, ['nonexistent']);
144+
echo "HEXPIRE myhash 10 FIELDS nonexistent: " . json_encode($hExpireResult4) . "\n"; // >>> [-2]
145+
// STEP_END
146+
147+
$this->assertEquals('OK', $hExpireResult1);
148+
$this->assertEquals([1, 1], $hExpireResult2);
149+
$this->assertEquals(2, count($hExpireResult3));
150+
$this->assertTrue(array_reduce($hExpireResult3, function($carry, $ttl) { return $carry && $ttl > 0; }, true)); // TTL should be positive
151+
$this->assertEquals([-2], $hExpireResult4);
152+
125153
echo "\n=== All Hash Commands Tests Passed! ===\n";
126154
}
127155

local_examples/cmds_hash/redis-py/cmds_hash.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,28 @@
105105
assert res11 == [ "Hello", "World" ]
106106
r.delete("myhash")
107107
# REMOVE_END
108+
# STEP_END
109+
110+
# STEP_START hexpire
111+
# Set up hash with fields
112+
r.hset("myhash", mapping={"field1": "Hello", "field2": "World"})
113+
114+
# Set expiration on hash fields
115+
res12 = r.hexpire("myhash", 10, "field1", "field2")
116+
print(res12) # >>> [1, 1]
117+
118+
# Check TTL of the fields
119+
res13 = r.httl("myhash", "field1", "field2")
120+
print(res13) # >>> [10, 10] (or close to 10)
121+
122+
# Try to set expiration on non-existent field
123+
res14 = r.hexpire("myhash", 10, "nonexistent")
124+
print(res14) # >>> [-2]
125+
126+
# REMOVE_START
127+
assert res12 == [1, 1]
128+
assert all(ttl > 0 for ttl in res13) # TTL should be positive
129+
assert res14 == [-2]
130+
r.delete("myhash")
131+
# REMOVE_END
108132
# STEP_END

0 commit comments

Comments
 (0)