From 8f77bcbfcb5735f12ab1c53b04c93bbb3c029505 Mon Sep 17 00:00:00 2001 From: Michael Deutsch Date: Thu, 14 Sep 2023 15:09:46 +0300 Subject: [PATCH 1/4] Pass in JsonSerializerOptions to generic methods addresses #186 --- src/NRedisStack/Json/IJsonCommands.cs | 10 ++++++---- src/NRedisStack/Json/IJsonCommandsAsync.cs | 4 +++- src/NRedisStack/Json/JsonCommands.cs | 4 ++-- src/NRedisStack/Json/JsonCommandsAsync.cs | 4 ++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/NRedisStack/Json/IJsonCommands.cs b/src/NRedisStack/Json/IJsonCommands.cs index 6ea7babe..8df8a4e2 100644 --- a/src/NRedisStack/Json/IJsonCommands.cs +++ b/src/NRedisStack/Json/IJsonCommands.cs @@ -1,5 +1,6 @@ using NRedisStack.Json.DataTypes; using StackExchange.Redis; +using System.Text.Json; namespace NRedisStack; @@ -103,7 +104,7 @@ public interface IJsonCommands /// sets the string that's printed at the end of each line /// sets the string that's put between a key and a value /// the path to get. - /// The requested Items + /// The requested items /// RedisResult Get(RedisKey key, RedisValue? indent = null, RedisValue? newLine = null, RedisValue? space = null, RedisValue? path = null); @@ -119,17 +120,18 @@ public interface IJsonCommands RedisResult Get(RedisKey key, string[] paths, RedisValue? indent = null, RedisValue? newLine = null, RedisValue? space = null); /// - /// Generically gets an Item stored in Redis. + /// Generically gets an item stored in Redis. /// /// The key to retrieve /// The path to retrieve + /// Json serializer options to use for deserialization. /// The type retrieved /// The object requested /// - T? Get(RedisKey key, string path = "$"); + T? Get(RedisKey key, string path = "$", JsonSerializerOptions serializerOptions? = default); /// - /// retrieves a group of items stored in redis, appropriate if the path will resolve to multiple records. + /// Retrieves a group of items stored in Redis, appropriate if the path will resolve to multiple records. /// /// The key to pull from. /// The path to pull. diff --git a/src/NRedisStack/Json/IJsonCommandsAsync.cs b/src/NRedisStack/Json/IJsonCommandsAsync.cs index 5e2a1351..1578bbd0 100644 --- a/src/NRedisStack/Json/IJsonCommandsAsync.cs +++ b/src/NRedisStack/Json/IJsonCommandsAsync.cs @@ -1,5 +1,6 @@ using NRedisStack.Json.DataTypes; using StackExchange.Redis; +using System.Text.Json; namespace NRedisStack; @@ -123,10 +124,11 @@ public interface IJsonCommandsAsync /// /// The key to retrieve /// The path to retrieve + /// Json serializer options to use for deserialization. /// The type retrieved /// The object requested /// - Task GetAsync(RedisKey key, string path = "$"); + Task GetAsync(RedisKey key, string path = "$", JsonSerializerOptions? serializerOptions = default); /// /// retrieves a group of items stored in redis, appropriate if the path will resolve to multiple records. diff --git a/src/NRedisStack/Json/JsonCommands.cs b/src/NRedisStack/Json/JsonCommands.cs index d1e588f7..e1eda143 100644 --- a/src/NRedisStack/Json/JsonCommands.cs +++ b/src/NRedisStack/Json/JsonCommands.cs @@ -222,7 +222,7 @@ public RedisResult Get(RedisKey key, string[] paths, RedisValue? indent = null, } /// - public T? Get(RedisKey key, string path = "$") + public T? Get(RedisKey key, string path = "$", JsonSerializerOptions serializerOptions? = default) { var res = _db.Execute(JsonCommandBuilder.Get(key, path)); if (res.Type == ResultType.BulkString) @@ -230,7 +230,7 @@ public RedisResult Get(RedisKey key, string[] paths, RedisValue? indent = null, var arr = JsonSerializer.Deserialize(res.ToString()!); if (arr?.Count > 0) { - return JsonSerializer.Deserialize(JsonSerializer.Serialize(arr[0])); + return JsonSerializer.Deserialize(JsonSerializer.Serialize(arr[0]), serializerOptions); } } diff --git a/src/NRedisStack/Json/JsonCommandsAsync.cs b/src/NRedisStack/Json/JsonCommandsAsync.cs index c42fcbd5..cc6b3b62 100644 --- a/src/NRedisStack/Json/JsonCommandsAsync.cs +++ b/src/NRedisStack/Json/JsonCommandsAsync.cs @@ -78,7 +78,7 @@ public async Task GetAsync(RedisKey key, string[] paths, RedisValue return await _db.ExecuteAsync(JsonCommandBuilder.Get(key, paths, indent, newLine, space)); } - public async Task GetAsync(RedisKey key, string path = "$") + public async Task GetAsync(RedisKey key, string path = "$", JsonSerializerOptions serializerOptions? = default) { var res = await _db.ExecuteAsync(JsonCommandBuilder.Get(key, path)); if (res.Type == ResultType.BulkString) @@ -86,7 +86,7 @@ public async Task GetAsync(RedisKey key, string[] paths, RedisValue var arr = JsonSerializer.Deserialize(res.ToString()!); if (arr?.Count > 0) { - return JsonSerializer.Deserialize(JsonSerializer.Serialize(arr[0])); + return JsonSerializer.Deserialize(JsonSerializer.Serialize(arr[0]), serializerOptions); } } From 48955976d415ddb5583639b83dce5b4375784a4d Mon Sep 17 00:00:00 2001 From: shacharPash Date: Thu, 14 Sep 2023 16:35:11 +0300 Subject: [PATCH 2/4] move the '?' to the right place --- src/NRedisStack/Json/IJsonCommands.cs | 2 +- src/NRedisStack/Json/JsonCommands.cs | 2 +- src/NRedisStack/Json/JsonCommandsAsync.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NRedisStack/Json/IJsonCommands.cs b/src/NRedisStack/Json/IJsonCommands.cs index 8df8a4e2..8c8621db 100644 --- a/src/NRedisStack/Json/IJsonCommands.cs +++ b/src/NRedisStack/Json/IJsonCommands.cs @@ -128,7 +128,7 @@ public interface IJsonCommands /// The type retrieved /// The object requested /// - T? Get(RedisKey key, string path = "$", JsonSerializerOptions serializerOptions? = default); + T? Get(RedisKey key, string path = "$", JsonSerializerOptions? serializerOptions = default); /// /// Retrieves a group of items stored in Redis, appropriate if the path will resolve to multiple records. diff --git a/src/NRedisStack/Json/JsonCommands.cs b/src/NRedisStack/Json/JsonCommands.cs index e1eda143..9f046833 100644 --- a/src/NRedisStack/Json/JsonCommands.cs +++ b/src/NRedisStack/Json/JsonCommands.cs @@ -222,7 +222,7 @@ public RedisResult Get(RedisKey key, string[] paths, RedisValue? indent = null, } /// - public T? Get(RedisKey key, string path = "$", JsonSerializerOptions serializerOptions? = default) + public T? Get(RedisKey key, string path = "$", JsonSerializerOptions? serializerOptions = default) { var res = _db.Execute(JsonCommandBuilder.Get(key, path)); if (res.Type == ResultType.BulkString) diff --git a/src/NRedisStack/Json/JsonCommandsAsync.cs b/src/NRedisStack/Json/JsonCommandsAsync.cs index cc6b3b62..889122b4 100644 --- a/src/NRedisStack/Json/JsonCommandsAsync.cs +++ b/src/NRedisStack/Json/JsonCommandsAsync.cs @@ -78,7 +78,7 @@ public async Task GetAsync(RedisKey key, string[] paths, RedisValue return await _db.ExecuteAsync(JsonCommandBuilder.Get(key, paths, indent, newLine, space)); } - public async Task GetAsync(RedisKey key, string path = "$", JsonSerializerOptions serializerOptions? = default) + public async Task GetAsync(RedisKey key, string path = "$", JsonSerializerOptions? serializerOptions = default) { var res = await _db.ExecuteAsync(JsonCommandBuilder.Get(key, path)); if (res.Type == ResultType.BulkString) From 1b2967000dc61f48956d4f79d79e9a4c3795bc88 Mon Sep 17 00:00:00 2001 From: Michael Deutsch Date: Thu, 14 Sep 2023 19:56:59 +0300 Subject: [PATCH 3/4] Add unit tests for JsonSerializerOptions --- tests/NRedisStack.Tests/Json/JsonTests.cs | 26 +++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/NRedisStack.Tests/Json/JsonTests.cs b/tests/NRedisStack.Tests/Json/JsonTests.cs index 94ee6afe..edd9f6c3 100644 --- a/tests/NRedisStack.Tests/Json/JsonTests.cs +++ b/tests/NRedisStack.Tests/Json/JsonTests.cs @@ -686,14 +686,21 @@ public async Task ForgetAsync() public void Get() { var commands = new JsonCommands(redisFixture.Redis.GetDatabase()); - var keys = CreateKeyNames(2); + var keys = CreateKeyNames(3); var key = keys[0]; var complexKey = keys[1]; + var caseInsensitiveKey = keys[2]; commands.Set(key, "$", new Person() { Age = 35, Name = "Alice" }); commands.Set(complexKey, "$", new { a = new Person() { Age = 35, Name = "Alice" }, b = new { a = new Person() { Age = 35, Name = "Alice" } } }); + commands.Set(caseInsensitiveKey, "$", new { name = "Alice", AGE = 35 }); var result = commands.Get(key); Assert.Equal("Alice", result!.Name); Assert.Equal(35, result.Age); + var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + result = commands.Get(caseInsensitiveKey, jsonOptions); + Assert.NotNull(result); + Assert.Equal("Alice", result.Name); + Assert.Equal(35, result.Age); var people = commands.GetEnumerable(complexKey, "$..a").ToArray(); Assert.Equal(2, people.Length); Assert.Equal("Alice", people[0]!.Name); @@ -706,14 +713,21 @@ public void Get() public async Task GetAsync() { var commands = new JsonCommandsAsync(redisFixture.Redis.GetDatabase()); - var keys = CreateKeyNames(2); + var keys = CreateKeyNames(3); var key = keys[0]; var complexKey = keys[1]; + var caseInsensitiveKey = keys[2]; await commands.SetAsync(key, "$", new Person() { Age = 35, Name = "Alice" }); await commands.SetAsync(complexKey, "$", new { a = new Person() { Age = 35, Name = "Alice" }, b = new { a = new Person() { Age = 35, Name = "Alice" } } }); + await commands.SetAsync(caseInsensitiveKey, "$", new { name = "Alice", AGE = 35 }); var result = await commands.GetAsync(key); Assert.Equal("Alice", result!.Name); Assert.Equal(35, result.Age); + var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + result = await commands.GetAsync(caseInsensitiveKey, jsonOptions); + Assert.NotNull(result); + Assert.Equal("Alice", result.Name); + Assert.Equal(35, result.Age); var people = (await commands.GetEnumerableAsync(complexKey, "$..a")).ToArray(); Assert.Equal(2, people.Length); Assert.Equal("Alice", people[0]!.Name); @@ -735,8 +749,8 @@ public void MSet() new KeyPathValue(key1, "$", new { a = "hello" }), new KeyPathValue(key2, "$", new { a = "world" }) }; - commands.MSet(values) -; + commands.MSet(values); + var result = commands.MGet(keys.Select(x => new RedisKey(x)).ToArray(), "$.a"); Assert.Equal("[\"hello\"]", result[0].ToString()); @@ -758,8 +772,8 @@ public async Task MSetAsync() new KeyPathValue(key1, "$", new { a = "hello" }), new KeyPathValue(key2, "$", new { a = "world" }) }; - await commands.MSetAsync(values) -; + await commands.MSetAsync(values); + var result = await commands.MGetAsync(keys.Select(x => new RedisKey(x)).ToArray(), "$.a"); Assert.Equal("[\"hello\"]", result[0].ToString()); From 6db97f990d2ea4e25532d9dc620e810674743098 Mon Sep 17 00:00:00 2001 From: Michael Deutsch Date: Thu, 14 Sep 2023 22:24:35 +0300 Subject: [PATCH 4/4] add missing json path --- tests/NRedisStack.Tests/Json/JsonTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/NRedisStack.Tests/Json/JsonTests.cs b/tests/NRedisStack.Tests/Json/JsonTests.cs index edd9f6c3..d8c4e76a 100644 --- a/tests/NRedisStack.Tests/Json/JsonTests.cs +++ b/tests/NRedisStack.Tests/Json/JsonTests.cs @@ -697,9 +697,9 @@ public void Get() Assert.Equal("Alice", result!.Name); Assert.Equal(35, result.Age); var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; - result = commands.Get(caseInsensitiveKey, jsonOptions); + result = commands.Get(caseInsensitiveKey, "$", jsonOptions); Assert.NotNull(result); - Assert.Equal("Alice", result.Name); + Assert.Equal("Alice", result!.Name); Assert.Equal(35, result.Age); var people = commands.GetEnumerable(complexKey, "$..a").ToArray(); Assert.Equal(2, people.Length); @@ -724,9 +724,9 @@ public async Task GetAsync() Assert.Equal("Alice", result!.Name); Assert.Equal(35, result.Age); var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; - result = await commands.GetAsync(caseInsensitiveKey, jsonOptions); + result = await commands.GetAsync(caseInsensitiveKey, "$", jsonOptions); Assert.NotNull(result); - Assert.Equal("Alice", result.Name); + Assert.Equal("Alice", result!.Name); Assert.Equal(35, result.Age); var people = (await commands.GetEnumerableAsync(complexKey, "$..a")).ToArray(); Assert.Equal(2, people.Length);