Skip to content

Commit b19be94

Browse files
committed
- add new messages
- add resultprocessors - fix test fails
1 parent ee91dc8 commit b19be94

File tree

5 files changed

+101
-24
lines changed

5 files changed

+101
-24
lines changed

src/StackExchange.Redis/Message.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ public static Message Create(int db, CommandFlags flags, RedisCommand command, i
310310
public static Message Create(int db, CommandFlags flags, RedisCommand command, in RedisValue value0, in RedisValue value1, in RedisValue value2, in RedisValue value3, in RedisValue value4) =>
311311
new CommandValueValueValueValueValueMessage(db, flags, command, value0, value1, value2, value3, value4);
312312

313+
public static Message Create(int db, CommandFlags flags, RedisCommand command, in RedisKey key, in RedisValue value0, in RedisValue value1, in RedisValue[] values) =>
314+
new CommandKeyValueValueValuesMessage(db, flags, command, key, value0, value1, values);
315+
313316
public static Message Create(
314317
int db,
315318
CommandFlags flags,
@@ -1177,6 +1180,36 @@ protected override void WriteImpl(PhysicalConnection physical)
11771180
public override int ArgCount => values.Length + 1;
11781181
}
11791182

1183+
private sealed class CommandKeyValueValueValuesMessage : CommandKeyBase
1184+
{
1185+
private readonly RedisValue value0;
1186+
private readonly RedisValue value1;
1187+
private readonly RedisValue[] values;
1188+
public CommandKeyValueValueValuesMessage(int db, CommandFlags flags, RedisCommand command, in RedisKey key, in RedisValue value0, in RedisValue value1, RedisValue[] values) : base(db, flags, command, key)
1189+
{
1190+
for (int i = 0; i < values.Length; i++)
1191+
{
1192+
values[i].AssertNotNull();
1193+
}
1194+
1195+
value0.AssertNotNull();
1196+
value1.AssertNotNull();
1197+
this.value0 = value0;
1198+
this.value1 = value1;
1199+
this.values = values;
1200+
}
1201+
1202+
protected override void WriteImpl(PhysicalConnection physical)
1203+
{
1204+
physical.WriteHeader(Command, values.Length + 3);
1205+
physical.Write(Key);
1206+
physical.WriteBulkString(value0);
1207+
physical.WriteBulkString(value1);
1208+
for (int i = 0; i < values.Length; i++) physical.WriteBulkString(values[i]);
1209+
}
1210+
public override int ArgCount => values.Length + 3;
1211+
}
1212+
11801213
private sealed class CommandKeyValueValueMessage : CommandKeyBase
11811214
{
11821215
private readonly RedisValue value0, value1;

src/StackExchange.Redis/RedisDatabase.cs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -448,41 +448,41 @@ private T HashFieldExecute<T, TProcessor>(RedisCommand cmd, RedisKey key, Custom
448448

449449
public RedisValue HashFieldGetAndDelete(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None)
450450
{
451-
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, hashField);
452-
return ExecuteSync(msg, ResultProcessor.RedisValue);
451+
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, RedisLiterals.FIELDS, 1, hashField);
452+
return ExecuteSync(msg, ResultProcessor.RedisValueFromArray);
453453
}
454454

455455
public Lease<byte>? HashFieldGetLeaseAndDelete(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None)
456456
{
457-
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, hashField);
458-
return ExecuteSync(msg, ResultProcessor.Lease);
457+
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, RedisLiterals.FIELDS, 1, hashField);
458+
return ExecuteSync(msg, ResultProcessor.LeaseFromArray);
459459
}
460460

461461
public RedisValue[] HashFieldGetAndDelete(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None)
462462
{
463463
if (hashFields == null) throw new ArgumentNullException(nameof(hashFields));
464464
if (hashFields.Length == 0) return Array.Empty<RedisValue>();
465-
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, hashFields);
465+
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, RedisLiterals.FIELDS, hashFields.Length, hashFields);
466466
return ExecuteSync(msg, ResultProcessor.RedisValueArray, defaultValue: Array.Empty<RedisValue>());
467467
}
468468

469469
public Task<RedisValue> HashFieldGetAndDeleteAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None)
470470
{
471-
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, hashField);
472-
return ExecuteAsync(msg, ResultProcessor.RedisValue);
471+
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, RedisLiterals.FIELDS, 1, hashField);
472+
return ExecuteAsync(msg, ResultProcessor.RedisValueFromArray);
473473
}
474474

475475
public Task<Lease<byte>?> HashFieldGetLeaseAndDeleteAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None)
476476
{
477-
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, hashField);
478-
return ExecuteAsync(msg, ResultProcessor.Lease);
477+
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, RedisLiterals.FIELDS, 1, hashField);
478+
return ExecuteAsync(msg, ResultProcessor.LeaseFromArray);
479479
}
480480

481481
public Task<RedisValue[]> HashFieldGetAndDeleteAsync(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None)
482482
{
483483
if (hashFields == null) throw new ArgumentNullException(nameof(hashFields));
484484
if (hashFields.Length == 0) return CompletedTask<RedisValue[]>.FromDefault(Array.Empty<RedisValue>(), asyncState);
485-
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, hashFields);
485+
var msg = Message.Create(Database, flags, RedisCommand.HGETDEL, key, RedisLiterals.FIELDS, hashFields.Length, hashFields);
486486
return ExecuteAsync(msg, ResultProcessor.RedisValueArray, defaultValue: Array.Empty<RedisValue>());
487487
}
488488

@@ -567,25 +567,25 @@ private Message HashFieldGetAndSetExpiryMessage<T>(RedisKey key, RedisValue[] ha
567567
public RedisValue HashFieldGetAndSetExpiry(RedisKey key, RedisValue hashField, TimeSpan? expiry = null, bool persist = false, CommandFlags flags = CommandFlags.None)
568568
{
569569
var msg = HashFieldGetAndSetExpiryMessage(key, hashField, expiry, CalculateExpiryValues, persist, flags);
570-
return ExecuteSync(msg, ResultProcessor.RedisValue);
570+
return ExecuteSync(msg, ResultProcessor.RedisValueFromArray);
571571
}
572572

573573
public RedisValue HashFieldGetAndSetExpiry(RedisKey key, RedisValue hashField, DateTime expiry, CommandFlags flags = CommandFlags.None)
574574
{
575575
var msg = HashFieldGetAndSetExpiryMessage(key, hashField, (DateTime?)expiry, CalculateExpiryValues, false, flags);
576-
return ExecuteSync(msg, ResultProcessor.RedisValue);
576+
return ExecuteSync(msg, ResultProcessor.RedisValueFromArray);
577577
}
578578

579579
public Lease<byte>? HashFieldGetLeaseAndSetExpiry(RedisKey key, RedisValue hashField, TimeSpan? expiry = null, bool persist = false, CommandFlags flags = CommandFlags.None)
580580
{
581581
var msg = HashFieldGetAndSetExpiryMessage(key, hashField, expiry, CalculateExpiryValues, persist, flags);
582-
return ExecuteSync(msg, ResultProcessor.Lease);
582+
return ExecuteSync(msg, ResultProcessor.LeaseFromArray);
583583
}
584584

585585
public Lease<byte>? HashFieldGetLeaseAndSetExpiry(RedisKey key, RedisValue hashField, DateTime expiry, CommandFlags flags = CommandFlags.None)
586586
{
587587
var msg = HashFieldGetAndSetExpiryMessage(key, hashField, (DateTime?)expiry, CalculateExpiryValues, false, flags);
588-
return ExecuteSync(msg, ResultProcessor.Lease);
588+
return ExecuteSync(msg, ResultProcessor.LeaseFromArray);
589589
}
590590

591591
public RedisValue[] HashFieldGetAndSetExpiry(RedisKey key, RedisValue[] hashFields, TimeSpan? expiry = null, bool persist = false, CommandFlags flags = CommandFlags.None)
@@ -607,25 +607,25 @@ public RedisValue[] HashFieldGetAndSetExpiry(RedisKey key, RedisValue[] hashFiel
607607
public Task<RedisValue> HashFieldGetAndSetExpiryAsync(RedisKey key, RedisValue hashField, TimeSpan? expiry = null, bool persist = false, CommandFlags flags = CommandFlags.None)
608608
{
609609
var msg = HashFieldGetAndSetExpiryMessage(key, hashField, expiry, CalculateExpiryValues, persist, flags);
610-
return ExecuteAsync(msg, ResultProcessor.RedisValue);
610+
return ExecuteAsync(msg, ResultProcessor.RedisValueFromArray);
611611
}
612612

613613
public Task<RedisValue> HashFieldGetAndSetExpiryAsync(RedisKey key, RedisValue hashField, DateTime expiry, CommandFlags flags = CommandFlags.None)
614614
{
615615
var msg = HashFieldGetAndSetExpiryMessage(key, hashField, (DateTime?)expiry, CalculateExpiryValues, false, flags);
616-
return ExecuteAsync(msg, ResultProcessor.RedisValue);
616+
return ExecuteAsync(msg, ResultProcessor.RedisValueFromArray);
617617
}
618618

619619
public Task<Lease<byte>?> HashFieldGetLeaseAndSetExpiryAsync(RedisKey key, RedisValue hashField, TimeSpan? expiry = null, bool persist = false, CommandFlags flags = CommandFlags.None)
620620
{
621621
var msg = HashFieldGetAndSetExpiryMessage(key, hashField, expiry, CalculateExpiryValues, persist, flags);
622-
return ExecuteAsync(msg, ResultProcessor.Lease);
622+
return ExecuteAsync(msg, ResultProcessor.LeaseFromArray);
623623
}
624624

625625
public Task<Lease<byte>?> HashFieldGetLeaseAndSetExpiryAsync(RedisKey key, RedisValue hashField, DateTime expiry, CommandFlags flags = CommandFlags.None)
626626
{
627627
var msg = HashFieldGetAndSetExpiryMessage(key, hashField, (DateTime?)expiry, CalculateExpiryValues, false, flags);
628-
return ExecuteAsync(msg, ResultProcessor.Lease);
628+
return ExecuteAsync(msg, ResultProcessor.LeaseFromArray);
629629
}
630630

631631
public Task<RedisValue[]> HashFieldGetAndSetExpiryAsync(RedisKey key, RedisValue[] hashFields, TimeSpan? expiry = null, bool persist = false, CommandFlags flags = CommandFlags.None)

src/StackExchange.Redis/RedisFeatures.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ namespace StackExchange.Redis
4545
v7_2_0_rc1 = new Version(7, 1, 240), // 7.2 RC1 is version 7.1.240
4646
v7_4_0_rc1 = new Version(7, 3, 240), // 7.4 RC1 is version 7.3.240
4747
v7_4_0_rc2 = new Version(7, 3, 241), // 7.4 RC2 is version 7.3.241
48-
v8_0_0_rc1 = new Version(7, 9, 240); // 8.0 RC1 is version 7.9.240
48+
v8_0_0_rc1 = new Version(7, 9, 0); // 8.0 RC1 is version 7.9.240
4949
#pragma warning restore SA1310 // Field names should not contain underscore
5050
#pragma warning restore SA1311 // Static readonly fields should begin with upper-case letter
5151

src/StackExchange.Redis/ResultProcessor.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,15 @@ public static readonly ResultProcessor<RedisType>
8787
public static readonly ResultProcessor<RedisValue>
8888
RedisValue = new RedisValueProcessor();
8989

90+
public static readonly ResultProcessor<RedisValue>
91+
RedisValueFromArray = new RedisValueFromArrayProcessor();
92+
9093
public static readonly ResultProcessor<Lease<byte>>
9194
Lease = new LeaseProcessor();
9295

96+
public static readonly ResultProcessor<Lease<byte>>
97+
LeaseFromArray = new LeaseFromArrayProcessor();
98+
9399
public static readonly ResultProcessor<RedisValue[]>
94100
RedisValueArray = new RedisValueArrayProcessor();
95101

@@ -1835,6 +1841,25 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
18351841
}
18361842
}
18371843

1844+
private sealed class RedisValueFromArrayProcessor : ResultProcessor<RedisValue>
1845+
{
1846+
protected override bool SetResultCore(PhysicalConnection connection, Message message, in RawResult result)
1847+
{
1848+
switch (result.Resp2TypeBulkString)
1849+
{
1850+
case ResultType.Array:
1851+
var items = result.GetItems();
1852+
if (items.Length == 1)
1853+
{ // treat an array of 1 like a single reply
1854+
SetResult(message, items[0].AsRedisValue());
1855+
return true;
1856+
}
1857+
break;
1858+
}
1859+
return false;
1860+
}
1861+
}
1862+
18381863
private sealed class RoleProcessor : ResultProcessor<Role>
18391864
{
18401865
protected override bool SetResultCore(PhysicalConnection connection, Message message, in RawResult result)
@@ -1980,6 +2005,25 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
19802005
}
19812006
}
19822007

2008+
private sealed class LeaseFromArrayProcessor : ResultProcessor<Lease<byte>>
2009+
{
2010+
protected override bool SetResultCore(PhysicalConnection connection, Message message, in RawResult result)
2011+
{
2012+
switch (result.Resp2TypeBulkString)
2013+
{
2014+
case ResultType.Array:
2015+
var items = result.GetItems();
2016+
if (items.Length == 1)
2017+
{ // treat an array of 1 like a single reply
2018+
SetResult(message, items[0].AsLease()!);
2019+
return true;
2020+
}
2021+
break;
2022+
}
2023+
return false;
2024+
}
2025+
}
2026+
19832027
private class ScriptResultProcessor : ResultProcessor<RedisResult>
19842028
{
19852029
public override bool SetResult(PhysicalConnection connection, Message message, in RawResult result)

tests/StackExchange.Redis.Tests/HashFieldTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ public void HashFieldGetAndSetExpiry()
330330
fieldResult = db.HashFieldGetAndSetExpiry(hashKey, "f1", persist: true);
331331
Assert.Equal(1, fieldResult);
332332
fieldTtl = db.HashFieldGetTimeToLive(hashKey, new RedisValue[] { "f1" })[0];
333-
Assert.Equal(0, fieldTtl);
333+
Assert.Equal(-1, fieldTtl);
334334

335335
// testing multiple fields with timespan
336336
db.HashSet(hashKey, entries);
@@ -352,7 +352,7 @@ public void HashFieldGetAndSetExpiry()
352352
fieldResults = db.HashFieldGetAndSetExpiry(hashKey, fields, persist: true);
353353
Assert.Equal(values, fieldResults);
354354
fieldTtls = db.HashFieldGetTimeToLive(hashKey, fields);
355-
Assert.Equal(new long[] { 0, 0 }, fieldTtls);
355+
Assert.Equal(new long[] { -1, -1 }, fieldTtls);
356356
}
357357

358358
[Fact]
@@ -379,7 +379,7 @@ public async void HashFieldGetAndSetExpiryAsync()
379379
fieldResult = await db.HashFieldGetAndSetExpiryAsync(hashKey, "f1", persist: true);
380380
Assert.Equal(1, fieldResult);
381381
fieldTtl = db.HashFieldGetTimeToLive(hashKey, new RedisValue[] { "f1" })[0];
382-
Assert.Equal(0, fieldTtl);
382+
Assert.Equal(-1, fieldTtl);
383383

384384
// testing multiple fields with timespan
385385
db.HashSet(hashKey, entries);
@@ -401,7 +401,7 @@ public async void HashFieldGetAndSetExpiryAsync()
401401
fieldResults = await db.HashFieldGetAndSetExpiryAsync(hashKey, fields, persist: true);
402402
Assert.Equal(values, fieldResults);
403403
fieldTtls = db.HashFieldGetTimeToLive(hashKey, fields);
404-
Assert.Equal(new long[] { 0, 0 }, fieldTtls);
404+
Assert.Equal(new long[] { -1, -1 }, fieldTtls);
405405
}
406406

407407
[Fact]
@@ -564,7 +564,7 @@ public async void HashFieldGetAndDeleteAsync()
564564
// multiple fields
565565
db.HashSet(hashKey, entries);
566566
var fieldResults = await db.HashFieldGetAndDeleteAsync(hashKey, fields);
567-
Assert.Equal(fields, fieldResults);
567+
Assert.Equal(values, fieldResults);
568568
Assert.False(db.HashExists(hashKey, "f1"));
569569
Assert.False(db.HashExists(hashKey, "f2"));
570570
}

0 commit comments

Comments
 (0)