diff --git a/JsonFlatFileDataStore.Test/CollectionModificationTests.cs b/JsonFlatFileDataStore.Test/CollectionModificationTests.cs index 8b2feb6..a707443 100644 --- a/JsonFlatFileDataStore.Test/CollectionModificationTests.cs +++ b/JsonFlatFileDataStore.Test/CollectionModificationTests.cs @@ -294,6 +294,55 @@ public async Task UpdateOneAsync_TypedModel_InnerSimpleIntArray() UTHelpers.Down(newFilePath); } + [Fact] + public async Task UpdateOneAsync_TypedModel_NestedArrays() + { + var newFilePath = UTHelpers.Up(); + + var store = new DataStore(newFilePath); + + var collection = store.GetCollection(); + Assert.Equal(0, collection.Count); + + var newModel = new TestModelWithNestedArray + { + Id = Guid.NewGuid().ToString(), + Type = "empty", + Fragments = new List> { new List { 1 }, new List { 2 }, new List { 3 } } + }; + + var insertResult = collection.InsertOne(newModel); + Assert.True(insertResult); + Assert.Equal(1, collection.Count); + + var store2 = new DataStore(newFilePath); + var collection2 = store2.GetCollection(); + Assert.Equal(1, collection2.Count); + + var updateData = new + { + Type = "filled", + Fragments = new List> + { + new List { 1 }, + new List { 2 }, + new List { 3 } + } + }; + + await collection2.UpdateOneAsync(e => e.Id == newModel.Id, updateData); + + var store3 = new DataStore(newFilePath); + var collection3 = store3.GetCollection(); + var updated = collection3.Find(e => e.Id == newModel.Id).First(); + Assert.Equal(3, updated.Fragments.Count()); + Assert.Equal(2, updated.Fragments.First().First()); + Assert.Equal(3, updated.Fragments.Last().First()); + Assert.Equal("filled", updated.Type); + + UTHelpers.Down(newFilePath); + } + [Fact] public async Task UpdateOneAsync_Predicate_Id_DynamicUser() { diff --git a/JsonFlatFileDataStore.Test/TestModels.cs b/JsonFlatFileDataStore.Test/TestModels.cs index 33618b6..e7d1e28 100644 --- a/JsonFlatFileDataStore.Test/TestModels.cs +++ b/JsonFlatFileDataStore.Test/TestModels.cs @@ -17,6 +17,13 @@ public class TestModelWithIntArray public List Fragments { get; set; } } + public class TestModelWithNestedArray + { + public string Id { get; set; } + public string Type { get; set; } + public List> Fragments { get; set; } + } + public class User { public int Id { get; set; } diff --git a/JsonFlatFileDataStore/ExpandoObjectConverter.cs b/JsonFlatFileDataStore/ExpandoObjectConverter.cs index 2a1a245..4fc4549 100644 --- a/JsonFlatFileDataStore/ExpandoObjectConverter.cs +++ b/JsonFlatFileDataStore/ExpandoObjectConverter.cs @@ -72,7 +72,7 @@ private static void AddPropertyToExpando(IDictionary expando, st } else { - // Handle other numeric types as needed + // TODO: Handle other numeric types as needed throw new JsonException("Unsupported numeric type"); } break; @@ -95,24 +95,120 @@ private static void AddPropertyToExpando(IDictionary expando, st var arrayValues = new List(); foreach (var arrayElement in propertyValue.EnumerateArray()) { - if (arrayElement.ValueKind == JsonValueKind.Object) + switch (arrayElement.ValueKind) { - var nestedExpandoInArray = new ExpandoObject(); - var nestedDictionaryInArray = (IDictionary)nestedExpandoInArray; - foreach (var nestedPropertyInArray in arrayElement.EnumerateObject()) - { - AddPropertyToExpando(nestedDictionaryInArray, nestedPropertyInArray.Name, nestedPropertyInArray.Value); - } - arrayValues.Add(nestedExpandoInArray); - } - else - { - arrayValues.Add(arrayElement.GetString()); // Adjust this for other value types if needed + case JsonValueKind.Undefined: + case JsonValueKind.Null: + arrayValues.Add(null); + break; + + case JsonValueKind.False: + arrayValues.Add(false); + break; + + case JsonValueKind.True: + arrayValues.Add(true); + break; + + case JsonValueKind.Number: + if (arrayElement.TryGetInt32(out int arrayElementIntValue)) + { + arrayValues.Add(arrayElementIntValue); + } + else if (arrayElement.TryGetInt64(out long longValue)) + { + arrayValues.Add(longValue); + } + else if (arrayElement.TryGetDouble(out double doubleValue)) + { + arrayValues.Add(doubleValue); + } + else if (arrayElement.TryGetDecimal(out decimal decimalValue)) + { + arrayValues.Add(decimalValue); + } + else + { + throw new JsonException("Unsupported numeric type"); + } + break; + + case JsonValueKind.String: + arrayValues.Add(arrayElement.GetString()); + break; + + case JsonValueKind.Object: + var nestedExpandoInArray = new ExpandoObject(); + var nestedDictionaryInArray = (IDictionary)nestedExpandoInArray; + foreach (var nestedPropertyInArray in arrayElement.EnumerateObject()) + { + AddPropertyToExpando(nestedDictionaryInArray, nestedPropertyInArray.Name, nestedPropertyInArray.Value); + } + arrayValues.Add(nestedExpandoInArray); + break; + + case JsonValueKind.Array: + // Recursively handle nested arrays + var nestedArray = new List(); + foreach (var nestedArrayElement in arrayElement.EnumerateArray()) + { + if (nestedArrayElement.ValueKind == JsonValueKind.Object) + { + var nestedExpandoInNestedArray = new ExpandoObject(); + var nestedDictionaryInNestedArray = (IDictionary)nestedExpandoInNestedArray; + foreach (var nestedPropertyInNestedArray in nestedArrayElement.EnumerateObject()) + { + AddPropertyToExpando(nestedDictionaryInNestedArray, nestedPropertyInNestedArray.Name, nestedPropertyInNestedArray.Value); + } + nestedArray.Add(nestedExpandoInNestedArray); + } + else if (nestedArrayElement.ValueKind == JsonValueKind.Array) + { + // Recursively handle deeper nested arrays + nestedArray.Add(ProcessNestedArray(nestedArrayElement)); + } + else + { + nestedArray.Add(nestedArrayElement.ToString()); + } + } + arrayValues.Add(nestedArray); + break; } } expando[propertyName] = arrayValues; break; } } + + private static object ProcessNestedArray(JsonElement arrayElement) + { + var arrayValues = new List(); + + foreach (var element in arrayElement.EnumerateArray()) + { + if (element.ValueKind == JsonValueKind.Object) + { + var nestedExpando = new ExpandoObject(); + var nestedDictionary = (IDictionary)nestedExpando; + foreach (var nestedProperty in element.EnumerateObject()) + { + AddPropertyToExpando(nestedDictionary, nestedProperty.Name, nestedProperty.Value); + } + arrayValues.Add(nestedExpando); + } + else if (element.ValueKind == JsonValueKind.Array) + { + // Recursively handle further nested arrays + arrayValues.Add(ProcessNestedArray(element)); + } + else + { + arrayValues.Add(element.ToString()); + } + } + + return arrayValues; + } } } \ No newline at end of file