From e4ea385d5f7e0ecb20c680cd9f98f1194b36b79b Mon Sep 17 00:00:00 2001 From: slorello89 Date: Wed, 23 Oct 2024 10:11:55 -0400 Subject: [PATCH] fixing issue with byte array updates --- .../Modeling/RedisCollectionStateManager.cs | 13 +++++++-- .../RediSearchTests/ObjectWithByteArray.cs | 15 +++++++++++ .../RediSearchTests/SearchFunctionalTests.cs | 15 +++++++++++ .../RediSearchTests/SearchTests.cs | 27 +++++++++++++++++++ .../RedisSetupCollection.cs | 2 ++ 5 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 test/Redis.OM.Unit.Tests/RediSearchTests/ObjectWithByteArray.cs diff --git a/src/Redis.OM/Modeling/RedisCollectionStateManager.cs b/src/Redis.OM/Modeling/RedisCollectionStateManager.cs index 534c601..20ec8eb 100644 --- a/src/Redis.OM/Modeling/RedisCollectionStateManager.cs +++ b/src/Redis.OM/Modeling/RedisCollectionStateManager.cs @@ -1,8 +1,8 @@ +using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Redis.OM.Modeling.Vectors; using JsonSerializer = System.Text.Json.JsonSerializer; namespace Redis.OM.Modeling @@ -329,7 +329,16 @@ private static JObject FindDiff(JToken currentObject, JToken snapshotObject) break; default: - if (currentObject.ToString() != snapshotObject.ToString()) + if (snapshotObject.Type == JTokenType.Bytes) + { + var snapShotObjectStr = Convert.ToBase64String(snapshotObject.Value()); + + if (snapShotObjectStr != currentObject.ToString()) + { + diff["+"] = currentObject.ToString(); + } + } + else if (currentObject.ToString() != snapshotObject.ToString()) { diff["+"] = currentObject; diff["-"] = snapshotObject; diff --git a/test/Redis.OM.Unit.Tests/RediSearchTests/ObjectWithByteArray.cs b/test/Redis.OM.Unit.Tests/RediSearchTests/ObjectWithByteArray.cs new file mode 100644 index 0000000..60756e4 --- /dev/null +++ b/test/Redis.OM.Unit.Tests/RediSearchTests/ObjectWithByteArray.cs @@ -0,0 +1,15 @@ +using Redis.OM.Modeling; + +namespace Redis.OM.Unit.Tests.RediSearchTests; + +[Document(StorageType = StorageType.Json, Prefixes = new []{"obj"})] +public class ObjectWithByteArray +{ + [RedisIdField] + [Indexed] + public string Id { get; set; } + + public byte[] Bytes1 { get; set; } + + public byte[] Bytes2 { get; set; } +} \ No newline at end of file diff --git a/test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs b/test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs index 6c36fe5..43d9468 100644 --- a/test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs +++ b/test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs @@ -1270,5 +1270,20 @@ public async Task TestSearchByMatchPattern(string pattern, int existingRecordsCo var res = await collection.Where(x => x.Name.MatchPattern(pattern)).ToListAsync(); Assert.Equal(existingRecordsCount, res.Count); } + + [Fact] + public async Task TestUpdateByteArray() + { + var collection = new RedisCollection(_connection); + var obj = new ObjectWithByteArray() { Bytes1 = new byte[] { 1, 2, 3 }, Bytes2 = new byte[] { 4, 5, 6 } }; + var id = await collection.InsertAsync(obj); + var res = (await collection.Where(x => x.Id == obj.Id).ToListAsync()).First(); + res.Bytes1 = new byte[] { 7, 8, 9 }; + res.Bytes2 = new byte[] { 10, 11, 12 }; + await collection.UpdateAsync(res); + var updated = (await collection.Where(x => x.Id == obj.Id).ToListAsync()).First(); + Assert.Equal(new byte[] { 7, 8, 9 }, updated.Bytes1); + Assert.Equal(new byte[] { 10, 11, 12 }, updated.Bytes2); + } } } \ No newline at end of file diff --git a/test/Redis.OM.Unit.Tests/RediSearchTests/SearchTests.cs b/test/Redis.OM.Unit.Tests/RediSearchTests/SearchTests.cs index c17749a..6eb09b9 100644 --- a/test/Redis.OM.Unit.Tests/RediSearchTests/SearchTests.cs +++ b/test/Redis.OM.Unit.Tests/RediSearchTests/SearchTests.cs @@ -60,6 +60,18 @@ public class SearchTests }) }; + private readonly RedisReply _mockedReplyObjectWIthMultipleByteArrays = new[] + { + new RedisReply(1), + new RedisReply( + "obj:01FVN836BNQGYMT80V7RCVY73N"), + new RedisReply(new RedisReply[] + { + "$", + "{\"Id\":\"01FVN836BNQGYMT80V7RCVY73N\",\"Bytes1\":\"AQID\",\"Bytes2\":\"BAUG\"}" + }) + }; + private readonly RedisReply _mockedReplyObjectWIthMultipleDateTimesHash = new[] { new RedisReply(1), @@ -1092,6 +1104,21 @@ public async Task TestUpdateJsonWithMultipleDateTimesHash() Scripts.ShaCollection.Clear(); } + [Fact] + public async Task TestUpdateJsonWithByteArrays() + { + _substitute.ExecuteAsync("FT.SEARCH", Arg.Any()).Returns(_mockedReplyObjectWIthMultipleByteArrays); + _substitute.ExecuteAsync("EVALSHA", Arg.Any()).Returns(Task.FromResult(new RedisReply("42"))); + _substitute.ExecuteAsync("SCRIPT", Arg.Any()) + .Returns(Task.FromResult(new RedisReply("cbbf1c4fab5064f419e469cc51c563f8bf51e6fb"))); + + var collection = new RedisCollection(_substitute); + var obj = (await collection.Where(x => x.Id == "01FVN836BNQGYMT80V7RCVY73N").ToListAsync()).First(); + obj.Bytes1 = new byte[] { 4, 5, 6 }; + await collection.UpdateAsync(obj); + await _substitute.Received().ExecuteAsync("EVALSHA", Arg.Any(), "1", new RedisKey("obj:01FVN836BNQGYMT80V7RCVY73N"), "SET", "$.Bytes1","\"BAUG\""); + } + [Fact] public async Task TestUpdateJsonUnloadedScriptAsync() { diff --git a/test/Redis.OM.Unit.Tests/RedisSetupCollection.cs b/test/Redis.OM.Unit.Tests/RedisSetupCollection.cs index c0a3eb1..7a60efb 100644 --- a/test/Redis.OM.Unit.Tests/RedisSetupCollection.cs +++ b/test/Redis.OM.Unit.Tests/RedisSetupCollection.cs @@ -31,6 +31,7 @@ public RedisSetup() Connection.CreateIndex(typeof(SelectTestObject)); Connection.CreateIndex(typeof(ObjectWithDateTimeOffsetJson)); Connection.CreateIndex(typeof(ObjectWithMultipleSearchableAttributes)); + Connection.CreateIndex(typeof(ObjectWithByteArray)); } private IRedisConnectionProvider _provider; @@ -64,6 +65,7 @@ public void Dispose() Connection.DropIndexAndAssociatedRecords(typeof(SelectTestObject)); Connection.DropIndexAndAssociatedRecords(typeof(ObjectWithDateTimeOffsetJson)); Connection.DropIndexAndAssociatedRecords(typeof(ObjectWithMultipleSearchableAttributes)); + Connection.DropIndexAndAssociatedRecords(typeof(ObjectWithByteArray)); } } }