From b82bff845fd8971e490ce20eabce3d4d03231cb1 Mon Sep 17 00:00:00 2001 From: Chanan Braunstein Date: Tue, 29 May 2018 22:49:48 -0600 Subject: [PATCH] Add Max Id to metadata --- src/BlazorDB/Storage/Metadata.cs | 1 + src/BlazorDB/Storage/StorageManagerSave.cs | 109 ++++++++++++++------- src/Sample/Pages/Index.cshtml | 3 + 3 files changed, 80 insertions(+), 33 deletions(-) diff --git a/src/BlazorDB/Storage/Metadata.cs b/src/BlazorDB/Storage/Metadata.cs index 2ba1074..185d92b 100644 --- a/src/BlazorDB/Storage/Metadata.cs +++ b/src/BlazorDB/Storage/Metadata.cs @@ -8,5 +8,6 @@ internal class Metadata public List Guids { get; set; } public string ModelName { get; set; } public string ContextName { get; set; } + public int MaxId { get; set; } } } \ No newline at end of file diff --git a/src/BlazorDB/Storage/StorageManagerSave.cs b/src/BlazorDB/Storage/StorageManagerSave.cs index 23e50e6..46e6cca 100644 --- a/src/BlazorDB/Storage/StorageManagerSave.cs +++ b/src/BlazorDB/Storage/StorageManagerSave.cs @@ -15,40 +15,59 @@ public int SaveContextToLocalStorage(StorageContext context) var contextType = context.GetType(); //Logger.ContextSaved(contextType); var storageSets = StorageManagerUtil.GetStorageSets(contextType); - total = SaveStorageSets(context, total, contextType, storageSets); + var metadataMap = LoadMetadataList(context, storageSets, contextType); + total = SaveStorageSets(context, total, contextType, storageSets, metadataMap); //Logger.EndGroup(); return total; } + private static IReadOnlyDictionary LoadMetadataList(StorageContext context, IEnumerable storageSets, Type contextType) + { + var map = new Dictionary(); + foreach (var prop in storageSets) + { + var modelType = prop.PropertyType.GetGenericArguments()[0]; + var storageTableName = Util.GetStorageTableName(contextType, modelType); + var metadata = StorageManagerUtil.LoadMetadata(storageTableName) ?? new Metadata + { + Guids = new List(), + ContextName = Util.GetFullyQualifiedTypeName(context.GetType()), + ModelName = Util.GetFullyQualifiedTypeName(modelType) + }; + map.Add(Util.GetFullyQualifiedTypeName(modelType), metadata); + } + + return map; + } + private static int SaveStorageSets(StorageContext context, int total, Type contextType, - List storageSets) + List storageSets, IReadOnlyDictionary metadataMap) { foreach (var prop in storageSets) { var storageSetValue = prop.GetValue(context); var modelType = prop.PropertyType.GetGenericArguments()[0]; var storageTableName = Util.GetStorageTableName(contextType, modelType); - EnsureAllModelsHaveIds(storageSetValue, modelType); - EnsureAllAssociationsHaveIds(context, storageSetValue, modelType, storageSets); - + + EnsureAllModelsHaveIds(storageSetValue, modelType, metadataMap); + EnsureAllAssociationsHaveIds(context, storageSetValue, modelType, storageSets, metadataMap); - var guids = SaveModels(context, storageSetValue, modelType, storageTableName, storageSets); + var guids = SaveModels(storageSetValue, modelType, storageTableName, storageSets); total += guids.Count; - var oldMetadata = StorageManagerUtil.LoadMetadata(storageTableName); - SaveMetadata(storageTableName, guids, contextType, modelType); - if (oldMetadata != null) DeleteOldModelsFromStorage(oldMetadata, storageTableName); + var oldMetadata = metadataMap[Util.GetFullyQualifiedTypeName(modelType)]; + SaveMetadata(storageTableName, guids, contextType, modelType, oldMetadata); + DeleteOldModelsFromStorage(oldMetadata, storageTableName); Logger.StorageSetSaved(modelType, guids.Count); } return total; } - private static void EnsureAllAssociationsHaveIds(StorageContext context, object storageSetValue, Type modelType, List storageSets) + private static void EnsureAllAssociationsHaveIds(StorageContext context, object storageSetValue, Type modelType, List storageSets, IReadOnlyDictionary metadataMap) { var storageSetType = StorageManagerUtil.GenericStorageSetType.MakeGenericType(modelType); var method = storageSetType.GetMethod(StorageManagerUtil.GetEnumerator); var enumerator = (IEnumerator)method.Invoke(storageSetValue, new object[] { }); - enumerator.Reset(); while (enumerator.MoveNext()) { var model = enumerator.Current; @@ -56,49 +75,71 @@ private static void EnsureAllAssociationsHaveIds(StorageContext context, object { if (prop.GetValue(model) == null || (!StorageManagerUtil.IsInContext(storageSets, prop) && !StorageManagerUtil.IsListInContext(storageSets, prop))) continue; - if (StorageManagerUtil.IsInContext(storageSets, prop)) EnsureOneAssociationHasId(context, model, prop, storageSets); - - + if (StorageManagerUtil.IsInContext(storageSets, prop)) EnsureOneAssociationHasId(context, prop.GetValue(model), prop.PropertyType, storageSets, metadataMap); + if (StorageManagerUtil.IsListInContext(storageSets, prop)) EnsureManyAssociationHasId(context, prop.GetValue(model), prop, storageSets, metadataMap); } } } - private static void EnsureOneAssociationHasId(StorageContext context, object model, PropertyInfo prop, List storageSets) + private static void EnsureManyAssociationHasId(StorageContext context, object listObject, PropertyInfo prop, List storageSets, IReadOnlyDictionary metadataMap) + { + Console.WriteLine("listObject: {0}", listObject); + var method = listObject.GetType().GetMethod(StorageManagerUtil.GetEnumerator); + var enumerator = (IEnumerator)method.Invoke(listObject, new object[] { }); + while (enumerator.MoveNext()) + { + var model = enumerator.Current; + EnsureOneAssociationHasId(context, model, prop.PropertyType.GetGenericArguments()[0], storageSets, metadataMap); + } + } + + private static void EnsureOneAssociationHasId(StorageContext context, object associatedModel, Type propType, List storageSets, IReadOnlyDictionary metadataMap) { - var associatedModel = prop.GetValue(model); var idProp = GetIdProperty(associatedModel); var id = Convert.ToString(idProp.GetValue(associatedModel)); + var metadata = metadataMap[Util.GetFullyQualifiedTypeName(propType)]; + Console.WriteLine("metadata: {0}", metadata.ModelName); + Console.WriteLine("maxId: {0}", metadata.MaxId); Console.WriteLine("id: {0}", id); - if (id == "0") SaveAssociationModel(context, associatedModel, prop, storageSets); + if (id == "0") + { + metadata.MaxId = metadata.MaxId + 1; + SaveAssociationModel(context, associatedModel, propType, storageSets, metadata.MaxId); + } + Console.WriteLine("maxId: {0}", metadata.MaxId); } - private static void EnsureAllModelsHaveIds(object storageSetValue, Type modelType) + private static void EnsureAllModelsHaveIds(object storageSetValue, Type modelType, IReadOnlyDictionary metadataMap) { var storageSetType = StorageManagerUtil.GenericStorageSetType.MakeGenericType(modelType); var method = storageSetType.GetMethod(StorageManagerUtil.GetEnumerator); + var metadata = metadataMap[Util.GetFullyQualifiedTypeName(modelType)]; var enumerator = (IEnumerator)method.Invoke(storageSetValue, new object[] { }); - var maxId = GetMaxId(enumerator); - enumerator.Reset(); while (enumerator.MoveNext()) { var model = enumerator.Current; - if (GetId(model) == 0) SetId(model, ++maxId); + if (GetId(model) == 0) + { + metadata.MaxId = metadata.MaxId + 1; + SetId(model, metadata.MaxId); + } } } - private static void SaveMetadata(string storageTableName, List guids, Type context, Type modelType) + private static void SaveMetadata(string storageTableName, List guids, Type context, Type modelType, Metadata oldMetadata) { var metadata = new Metadata { Guids = guids, ContextName = Util.GetFullyQualifiedTypeName(context), - ModelName = Util.GetFullyQualifiedTypeName(modelType) + ModelName = Util.GetFullyQualifiedTypeName(modelType), + MaxId = oldMetadata.MaxId }; var name = $"{storageTableName}-{StorageManagerUtil.Metadata}"; BlazorDBInterop.SetItem(name, JsonUtil.Serialize(metadata), false); } - private static List SaveModels(StorageContext context, object storageSetValue, Type modelType, string storageTableName, + private static List SaveModels(object storageSetValue, Type modelType, string storageTableName, List storageSets) { var guids = new List(); @@ -111,7 +152,7 @@ private static List SaveModels(StorageContext context, object storageSetVa guids.Add(guid); var model = enumerator.Current; var name = $"{storageTableName}-{guid}"; - var serializedModel = ScanModelForAssociations(context, storageSetValue, model, storageSets, JsonUtil.Serialize(model)); + var serializedModel = ScanModelForAssociations(model, storageSets, JsonUtil.Serialize(model)); BlazorDBInterop.SetItem(name, serializedModel, false); } @@ -140,7 +181,7 @@ private static void DeleteOldModelsFromStorage(Metadata metadata, string storage } } - private static string ScanModelForAssociations(StorageContext context, object storageSetValue, object model, List storageSets, + private static string ScanModelForAssociations(object model, List storageSets, string serializedModel) { var result = serializedModel; @@ -148,7 +189,7 @@ private static string ScanModelForAssociations(StorageContext context, object st { if (prop.GetValue(model) == null || (!StorageManagerUtil.IsInContext(storageSets, prop) && !StorageManagerUtil.IsListInContext(storageSets, prop))) continue; - if (StorageManagerUtil.IsInContext(storageSets, prop)) result = FixOneAssociation(context, storageSetValue, model, prop, result, storageSets); + if (StorageManagerUtil.IsInContext(storageSets, prop)) result = FixOneAssociation(model, prop, result); if (StorageManagerUtil.IsListInContext(storageSets, prop)) result = FixManyAssociation(model, prop, result); } @@ -170,7 +211,7 @@ private static string FixManyAssociation(object model, PropertyInfo prop, string return result; } - private static string FixOneAssociation(StorageContext context, object storageSetValue, object model, PropertyInfo prop, string result, List storageSets) + private static string FixOneAssociation(object model, PropertyInfo prop, string result) { var associatedModel = prop.GetValue(model); var idProp = GetIdProperty(associatedModel); @@ -182,12 +223,14 @@ private static string FixOneAssociation(StorageContext context, object storageSe return result; } - private static string SaveAssociationModel(StorageContext context, object associatedModel, PropertyInfo prop, List storageSets) + private static int SaveAssociationModel(StorageContext context, object associatedModel, Type propType, IEnumerable storageSets, int id) { + Console.WriteLine("SaveAssociationModel id: {0}", id); Console.WriteLine("associatedModel: {0}", associatedModel); + Console.WriteLine("propType: {0}", propType); var q = from p in storageSets - where p.PropertyType.GetGenericArguments()[0] == prop.PropertyType - select p; + where p.PropertyType.GetGenericArguments()[0] == propType + select p; var storeageSetProp = q.Single(); Console.WriteLine("storeageSetProp: {0}", storeageSetProp); var storeageSet = storeageSetProp.GetValue(context); @@ -195,9 +238,9 @@ where p.PropertyType.GetGenericArguments()[0] == prop.PropertyType var listProp = storeageSet.GetType().GetProperty(StorageManagerUtil.List, StorageManagerUtil.Flags); var list = listProp.GetValue(storeageSet); var addMethod = list.GetType().GetMethod(StorageManagerUtil.Add); - SetId(associatedModel, 999); + SetId(associatedModel, id); addMethod.Invoke(list, new[] { associatedModel }); - return "999"; + return id; } private static string ReplaceModelWithId(string result, string serializedItem, string id) diff --git a/src/Sample/Pages/Index.cshtml b/src/Sample/Pages/Index.cshtml index e87eb53..589177f 100644 --- a/src/Sample/Pages/Index.cshtml +++ b/src/Sample/Pages/Index.cshtml @@ -26,6 +26,9 @@ { //In this case, address gets serailized as part of the object because Address is not in the Context var person = new Person { FirstName = "John", LastName = "Smith", HomeAddress = new Address { Street = "221 Baker Street", City = "This should be part of the json, since address is not in context (Very long city)" } }; + var address1 = new Address { Street = "Many test 1", City = "Saved as a reference" }; + var address2 = new Address { Street = "Many test 2", City = "Saved as a reference" }; + person.OtherAddresses = new List
{ address1, address2 }; Context.People.Add(person); }