Skip to content

Commit 8f0833a

Browse files
committed
- fix snafu with NOCASE (logic inverted)
- add IsReversed to simplify reversal logic
1 parent bd2a816 commit 8f0833a

4 files changed

Lines changed: 64 additions & 24 deletions

File tree

docs/ReleaseNotes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Current package versions:
88

99
## Unreleased
1010

11-
- (none)
11+
- Fix logic inversion with `ARGREP NOCASE`, and add `IsReversed` to simplify ordering
1212

1313
## 2.13.10
1414

src/StackExchange.Redis/ArrayGrepRequest.cs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.ComponentModel;
34
using System.Diagnostics.CodeAnalysis;
45
using RESPite;
56

@@ -16,12 +17,14 @@ private enum LocalFlags : byte
1617
{
1718
None = 0,
1819
IsFrozen = 1 << 0,
19-
CaseSensitive = 1 << 1,
20+
CaseInsensitive = 1 << 1,
2021
IsIntersection = 1 << 2,
2122
StartSpecified = 1 << 3,
2223
EndSpecified = 1 << 4,
2324
LimitSpecified = 1 << 5,
2425
IncludeValues = 1 << 6,
26+
Reversed = 1 << 7,
27+
// warning: next flag needs : ushort
2528
}
2629

2730
private void Freeze() => _flags |= LocalFlags.IsFrozen;
@@ -131,13 +134,37 @@ public long? Limit
131134
private long _limit;
132135

133136
/// <summary>
134-
/// Indicates whether matches are performed in a case-insensitive manner.
137+
/// Indicates whether matches are performed in a case-sensitive manner.
135138
/// </summary>
136139
/// <remarks>Corresponds to the <c>NOCASE</c> parameter.</remarks>
140+
[Browsable(false)]
141+
[EditorBrowsable(EditorBrowsableState.Never)]
142+
[Obsolete("Prefer " + nameof(IsCaseInsensitive))]
137143
public bool IsCaseSensitive
138144
{
139-
get => GetFlag(LocalFlags.CaseSensitive);
140-
set => SetFlag(LocalFlags.CaseSensitive, value);
145+
get => !IsCaseInsensitive;
146+
set => IsCaseInsensitive = !value;
147+
}
148+
149+
/// <summary>
150+
/// Indicates whether matches are performed in a case-insensitive manner.
151+
/// </summary>
152+
/// <remarks>Corresponds to the <c>NOCASE</c> parameter.</remarks>
153+
public bool IsCaseInsensitive
154+
{
155+
get => GetFlag(LocalFlags.CaseInsensitive);
156+
set => SetFlag(LocalFlags.CaseInsensitive, value);
157+
}
158+
159+
/// <summary>
160+
/// Indicates whether the query order should be reversed; this is equivalent to
161+
/// reversing the order of <see cref="Start"/> and <see cref="End"/>.
162+
/// </summary>
163+
/// <remarks>Corresponds to the <c>NOCASE</c> parameter.</remarks>
164+
public bool IsReversed
165+
{
166+
get => GetFlag(LocalFlags.Reversed);
167+
set => SetFlag(LocalFlags.Reversed, value);
141168
}
142169

143170
/// <summary>
@@ -317,35 +344,38 @@ public override int ArgCount
317344
}
318345

319346
if (request.IsIntersection) count++;
320-
if (request.IsCaseSensitive) count++;
347+
if (request.IsCaseInsensitive) count++;
321348
if (request.IncludeValues) count++;
322349
var limit = request.Limit;
323350
if (limit.HasValue) count += 2;
324351
return count;
325352
}
326353
}
327354

328-
protected override void WriteImpl(PhysicalConnection physical)
355+
private static void AddIndex(PhysicalConnection physical, RedisArrayIndex? index, ReadOnlySpan<byte> fallback)
329356
{
330-
physical.WriteHeader(Command, ArgCount);
331-
physical.WriteBulkString(key);
332-
var index = request.Start;
333357
if (index.HasValue)
334358
{
335359
physical.WriteBulkString(index.GetValueOrDefault().Value);
336360
}
337361
else
338362
{
339-
physical.WriteRaw("$1\r\n-\r\n"u8);
363+
physical.WriteRaw(fallback);
340364
}
341-
index = request.End;
342-
if (index.HasValue)
365+
}
366+
protected override void WriteImpl(PhysicalConnection physical)
367+
{
368+
physical.WriteHeader(Command, ArgCount);
369+
physical.WriteBulkString(key);
370+
if (request.IsReversed)
343371
{
344-
physical.WriteBulkString(index.GetValueOrDefault().Value);
372+
AddIndex(physical, request.End, "$1\r\n+\r\n"u8);
373+
AddIndex(physical, request.Start, "$1\r\n-\r\n"u8);
345374
}
346375
else
347376
{
348-
physical.WriteRaw("$1\r\n+\r\n"u8);
377+
AddIndex(physical, request.Start, "$1\r\n-\r\n"u8);
378+
AddIndex(physical, request.End, "$1\r\n+\r\n"u8);
349379
}
350380
var pCount = request.Count;
351381
for (int i = 0; i < pCount; i++)
@@ -354,7 +384,7 @@ protected override void WriteImpl(PhysicalConnection physical)
354384
}
355385

356386
if (request.IsIntersection) physical.WriteRaw("$3\r\nAND\r\n"u8);
357-
if (request.IsCaseSensitive) physical.WriteRaw("$6\r\nNOCASE\r\n"u8);
387+
if (request.IsCaseInsensitive) physical.WriteRaw("$6\r\nNOCASE\r\n"u8);
358388
if (request.IncludeValues) physical.WriteRaw("$10\r\nWITHVALUES\r\n"u8);
359389
var limit = request.Limit;
360390
if (limit.HasValue)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
#nullable enable
2+
[SER006]StackExchange.Redis.ArrayGrepRequest.IsCaseInsensitive.get -> bool
3+
[SER006]StackExchange.Redis.ArrayGrepRequest.IsCaseInsensitive.set -> void
4+
[SER006]StackExchange.Redis.ArrayGrepRequest.IsReversed.get -> bool
5+
[SER006]StackExchange.Redis.ArrayGrepRequest.IsReversed.set -> void

tests/StackExchange.Redis.Tests/ArrayTests.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ public async Task GrepBasics()
240240
Assert.Equal(4, await db.ArraySetAsync(key, [Entry(0, "RedisArray"), Entry(1, "redis-match"), Entry(2, "array-only"), Entry(3, "plain")]));
241241
var andNoCase = CreateGrep(ArrayGrepRequest.Predicate.Match("redis"), ArrayGrepRequest.Predicate.Glob("*array*"));
242242
andNoCase.IsIntersection = true;
243-
andNoCase.IsCaseSensitive = true;
243+
andNoCase.IsCaseInsensitive = true;
244244
AssertIndexEntries(await db.ArrayGrepAsync(key, andNoCase), 0);
245245

246246
await db.KeyDeleteAsync(key);
@@ -264,7 +264,7 @@ public async Task GrepRegexAndErrors()
264264
AssertIndexEntries(await db.ArrayGrepAsync(key, CreateGrep(ArrayGrepRequest.Predicate.Regex("^.*[0-9]{3}$"))), 0, 2, 3);
265265

266266
var noCase = CreateGrep(ArrayGrepRequest.Predicate.Regex("^foo[0-9]+$"));
267-
noCase.IsCaseSensitive = true;
267+
noCase.IsCaseInsensitive = true;
268268
AssertIndexEntries(await db.ArrayGrepAsync(key, noCase), 0, 3);
269269

270270
await db.KeyDeleteAsync(key);
@@ -277,29 +277,35 @@ public async Task GrepRegexAndErrors()
277277

278278
AssertIndexEntries(await db.ArrayGrepAsync(key, CreateGrep(ArrayGrepRequest.Predicate.Regex("foo|bar"))), 0, 1, 3, 5, 6);
279279
noCase = CreateGrep(ArrayGrepRequest.Predicate.Regex("foo|bar"));
280-
noCase.IsCaseSensitive = true;
280+
noCase.IsCaseInsensitive = true;
281281
AssertIndexEntries(await db.ArrayGrepAsync(key, noCase), 0, 1, 3, 4, 5, 6);
282282

283+
// and same again, with reversed start/end
284+
noCase = CreateGrep(ArrayGrepRequest.Predicate.Regex("foo|bar"));
285+
noCase.IsCaseInsensitive = true;
286+
noCase.IsReversed = true;
287+
AssertIndexEntries(await db.ArrayGrepAsync(key, noCase), 6, 5, 4, 3, 1, 0);
288+
283289
noCase = CreateGrep(ArrayGrepRequest.Predicate.Regex("^(foo|bar)$"));
284-
noCase.IsCaseSensitive = true;
290+
noCase.IsCaseInsensitive = true;
285291
AssertIndexEntries(await db.ArrayGrepAsync(key, noCase), 0, 1, 4);
286292

287293
noCase = CreateGrep(ArrayGrepRequest.Predicate.Regex("^(foo|bar)"));
288-
noCase.IsCaseSensitive = true;
294+
noCase.IsCaseInsensitive = true;
289295
AssertIndexEntries(await db.ArrayGrepAsync(key, noCase), 0, 1, 3, 4);
290296

291297
noCase = CreateGrep(ArrayGrepRequest.Predicate.Regex("(foo|bar)$"));
292-
noCase.IsCaseSensitive = true;
298+
noCase.IsCaseInsensitive = true;
293299
AssertIndexEntries(await db.ArrayGrepAsync(key, noCase), 0, 1, 3, 4, 5, 6);
294300

295301
noCase = CreateGrep(ArrayGrepRequest.Predicate.Regex("alpha|alps"));
296-
noCase.IsCaseSensitive = true;
302+
noCase.IsCaseInsensitive = true;
297303
AssertIndexEntries(await db.ArrayGrepAsync(key, noCase), 8, 9);
298304

299305
await db.KeyDeleteAsync(key);
300306
Assert.Equal(4, await db.ArraySetAsync(key, [Entry(0, "item-foo-123"), Entry(1, "ITEM-BAR-456"), Entry(2, "item-baz"), Entry(3, "plain")]));
301307
noCase = CreateGrep(ArrayGrepRequest.Predicate.Regex("^item-(foo|bar)-[0-9]{3}$"));
302-
noCase.IsCaseSensitive = true;
308+
noCase.IsCaseInsensitive = true;
303309
AssertIndexEntries(await db.ArrayGrepAsync(key, noCase), 0, 1);
304310

305311
await db.KeyDeleteAsync(key);

0 commit comments

Comments
 (0)