Esempio n. 1
0
        private static void EnsureAllAssociationsHaveIds(StorageContext context, object storageSetValue, Type modelType,
                                                         List <PropertyInfo> storageSets, IReadOnlyDictionary <string, Metadata> metadataMap)
        {
            var storageSetType = StorageManagerUtil.GenericStorageSetType.MakeGenericType(modelType);
            var method         = storageSetType.GetMethod(StorageManagerUtil.GetEnumerator);
            var enumerator     = (IEnumerator)method.Invoke(storageSetValue, new object[] { });

            while (enumerator.MoveNext())
            {
                var model = enumerator.Current;
                foreach (var prop in model.GetType().GetProperties())
                {
                    if (prop.GetValue(model) == null || !StorageManagerUtil.IsInContext(storageSets, prop) &&
                        !StorageManagerUtil.IsListInContext(storageSets, prop))
                    {
                        continue;
                    }
                    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);
                    }
                }
            }
        }
Esempio n. 2
0
        private static object CreateContext(Type contextType,
                                            IReadOnlyDictionary <Type, Dictionary <int, SerializedModel> > stringModels)
        {
            var context = Activator.CreateInstance(contextType);

            foreach (var prop in contextType.GetProperties())
            {
                if (prop.PropertyType.IsGenericType &&
                    prop.PropertyType.GetGenericTypeDefinition() == typeof(StorageSet <>))
                {
                    var modelType        = prop.PropertyType.GetGenericArguments()[0];
                    var storageSetType   = StorageManagerUtil.GenericStorageSetType.MakeGenericType(modelType);
                    var storageTableName = Util.GetStorageTableName(contextType, modelType);
                    var metadata         = StorageManagerUtil.LoadMetadata(storageTableName);
                    if (stringModels.ContainsKey(modelType))
                    {
                        var map = stringModels[modelType];
                        Logger.LoadModelInContext(modelType, map.Count);
                    }
                    else
                    {
                        Logger.LoadModelInContext(modelType, 0);
                    }

                    var storageSet = metadata != null
                        ? LoadStorageSet(storageSetType, contextType, modelType, stringModels[modelType])
                        : CreateNewStorageSet(storageSetType, contextType);

                    prop.SetValue(context, storageSet);
                }
            }

            return(context);
        }
Esempio n. 3
0
        private static Dictionary <Type, Dictionary <int, SerializedModel> > LoadStringModels(Type contextType,
                                                                                              IEnumerable <PropertyInfo> storageSets)
        {
            var stringModels = new Dictionary <Type, Dictionary <int, SerializedModel> >();

            foreach (var prop in storageSets)
            {
                var modelType        = prop.PropertyType.GetGenericArguments()[0];
                var map              = new Dictionary <int, SerializedModel>();
                var storageTableName = Util.GetStorageTableName(contextType, modelType);
                var metadata         = StorageManagerUtil.LoadMetadata(storageTableName);
                if (metadata == null)
                {
                    continue;
                }
                foreach (var guid in metadata.Guids)
                {
                    var name            = $"{storageTableName}-{guid}";
                    var serializedModel = BlazorDBInterop.GetItem(name, false);
                    var id = FindIdInSerializedModel(serializedModel);
                    map.Add(id, new SerializedModel {
                        StringModel = serializedModel
                    });
                }

                stringModels.Add(modelType, map);
            }

            return(stringModels);
        }
        private string FixAssociationsInStringModels(SerializedModel stringModel, Type modelType, List <PropertyInfo> storageSets, Dictionary <Type, Dictionary <int, SerializedModel> > stringModels)
        {
            var result = stringModel.StringModel;

            foreach (var prop in modelType.GetProperties())
            {
                if (StorageManagerUtil.IsInContext(storageSets, prop))
                {
                    if (TryGetIdFromSerializedModel(result, prop.Name, out var id))
                    {
                        var updated = GetAssociatedStringModel(stringModels, prop.PropertyType, id);
                        result = ReplaceIdWithAssociation(result, prop.Name, id, updated);
                    }
                }
                if (StorageManagerUtil.IsListInContext(storageSets, prop))
                {
                    if (TryGetIdListFromSerializedModel(result, prop.Name, out var idList))
                    {
                        var sb = new StringBuilder();
                        foreach (var id in idList)
                        {
                            var updated = GetAssociatedStringModel(stringModels, prop.PropertyType.GetGenericArguments()[0], id);
                            sb.Append(updated).Append(",");
                        }
                        var strList = sb.ToString().Substring(0, sb.ToString().Length - 1);
                        result = ReplaceListWithAssociationList(result, prop.Name, strList);
                    }
                }
            }
            return(result);
        }
Esempio n. 5
0
        public async Task <int> SaveContextToLocalStorage(StorageContext context)
        {
            var total       = 0;
            var contextType = context.GetType();
            await Logger.ContextSaved(contextType);

            var storageSets = StorageManagerUtil.GetStorageSets(contextType);
            var error       = ValidateModels(context, storageSets);

            if (error == null)
            {
                var metadataMap = await LoadMetadataList(context, storageSets, contextType);

                total = await SaveStorageSets(context, total, contextType, storageSets, metadataMap);

                Logger.EndGroup();
            }
            else
            {
                await BlazorLogger.Logger.Error("SaveChanges() terminated due to validation error");

                Logger.EndGroup();
                throw new BlazorDBUpdateException(error);
            }

            return(total);
        }
Esempio n. 6
0
        private string ScanModelForAssociations(object model, List <PropertyInfo> storageSets, string serializedModel)
        {
            var result = serializedModel;

            foreach (var prop in model.GetType().GetProperties())
            {
                if (prop.GetValue(model) != null && StorageManagerUtil.IsInContext(storageSets, prop))
                {
                    var associatedModel = prop.GetValue(model);
                    var idProp          = associatedModel.GetType().GetProperty(StorageManagerUtil.ID); //TODO: Handle missing Id prop
                    var id             = Convert.ToString(idProp.GetValue(associatedModel));
                    var serializedItem = JsonUtil.Serialize(model);
                    result = ReplaceModelWithId(result, serializedItem, id);
                }
                if (prop.GetValue(model) != null && StorageManagerUtil.IsListInContext(storageSets, prop))
                {
                    var modelList = (IEnumerable)prop.GetValue(model);
                    foreach (var item in modelList)
                    {
                        var idProp         = item.GetType().GetProperty(StorageManagerUtil.ID); //TODO: Handle missing Id prop
                        var id             = Convert.ToString(idProp.GetValue(item));
                        var serializedItem = JsonUtil.Serialize(item);
                        result = ReplaceModelWithId(result, serializedItem, id);
                    }
                }
            }
            return(result);
        }
Esempio n. 7
0
        private static string ReplaceIdWithAssociation(string result, string name, int id, string stringModel)
        {
            var stringToFind = $"\"{name}\":{id}";
            var nameIndex    = result.IndexOf(stringToFind, StringComparison.Ordinal);
            var index        = result.IndexOf(id.ToString(), nameIndex, StringComparison.Ordinal);

            result = StorageManagerUtil.ReplaceString(result, index, index + id.ToString().Length, stringModel);
            return(result);
        }
Esempio n. 8
0
        private static string ReplaceListWithAssociationList(string serializedModel, string propName, string strList)
        {
            var propStart = serializedModel.IndexOf($"\"{propName}\":[", StringComparison.Ordinal);
            var start     = serializedModel.IndexOf('[', propStart) + 1;
            var end       = serializedModel.IndexOf(']', start);
            var result    = StorageManagerUtil.ReplaceString(serializedModel, start, end, strList);

            return(result);
        }
Esempio n. 9
0
        private static Dictionary <Type, Dictionary <int, SerializedModel> > DeserializeModels(
            Dictionary <Type, Dictionary <int, SerializedModel> > stringModels, List <PropertyInfo> storageSets)
        {
            foreach (var map in stringModels)
            {
                var modelType = map.Key;
                foreach (var sm in map.Value)
                {
                    var stringModel = sm.Value;
                    if (!stringModel.HasAssociation)
                    {
                        stringModel.Model = DeserializeModel(modelType, stringModel.StringModel);
                    }
                }
            }

            foreach (var map in stringModels) //TODO: Fix associations that are more than one level deep
            {
                var modelType = map.Key;
                foreach (var sm in map.Value)
                {
                    var stringModel = sm.Value;
                    if (stringModel.Model != null)
                    {
                        continue;
                    }
                    var model = DeserializeModel(modelType, stringModel.StringModel);
                    foreach (var prop in model.GetType().GetProperties())
                    {
                        if (StorageManagerUtil.IsInContext(storageSets, prop) && prop.GetValue(model) != null)
                        {
                            var associatedLocalModel = prop.GetValue(model);
                            var localIdProp          =
                                associatedLocalModel.GetType()
                                .GetProperty(StorageManagerUtil.Id);
                            if (localIdProp == null)
                            {
                                throw new ArgumentException("Model must have Id property");
                            }
                            var localId = Convert.ToInt32(localIdProp.GetValue(associatedLocalModel));
                            var associatdRemoteModel =
                                GetModelFromStringModels(stringModels, associatedLocalModel.GetType(), localId)
                                .Model;
                            prop.SetValue(model, associatdRemoteModel);
                        }
                    }

                    stringModel.Model = model;
                }
            }

            return(stringModels);
        }
Esempio n. 10
0
        public int SaveContextToLocalStorage(StorageContext context)
        {
            int total       = 0;
            var contextType = context.GetType();

            Logger.ContextSaved(contextType);
            var storageSets = StorageManagerUtil.GetStorageSets(contextType);

            total = SaveStorageSets(context, total, contextType, storageSets);
            Logger.EndGroup();
            return(total);
        }
        private bool HasListAssociation(List <PropertyInfo> storageSets, Type modelType, SerializedModel stringModel)
        {
            var found = false;

            foreach (var prop in modelType.GetProperties())
            {
                if (StorageManagerUtil.IsListInContext(storageSets, prop))
                {
                    found = true;
                    break;
                }
            }
            return(found);
        }
Esempio n. 12
0
        public void LoadContextFromStorageOrCreateNew(IServiceCollection serviceCollection, Type contextType)
        {
            Logger.StartContextType(contextType);
            var storageSets  = StorageManagerUtil.GetStorageSets(contextType);
            var stringModels = LoadStringModels(contextType, storageSets);

            //PrintStringModels(stringModels);
            stringModels = ScanNonAssociationModels(storageSets, stringModels);
            stringModels = ScanAssociationModels(storageSets, stringModels);
            stringModels = DeserializeModels(stringModels, storageSets);
            //PrintStringModels(stringModels);
            var context = CreateContext(contextType, stringModels);

            RegisterContext(serviceCollection, contextType, context);
            Logger.EndGroup();
        }
Esempio n. 13
0
        public async Task LoadContextFromLocalStorage(StorageContext context)
        {
            var contextType = context.GetType();
            await Logger.StartContextType(contextType);

            var storageSets  = StorageManagerUtil.GetStorageSets(contextType);
            var stringModels = await LoadStringModels(contextType, storageSets);

            //PrintStringModels(stringModels);
            stringModels = ScanNonAssociationModels(storageSets, stringModels);
            stringModels = ScanAssociationModels(storageSets, stringModels);
            stringModels = DeserializeModels(stringModels, storageSets);
            //PrintStringModels(stringModels);
            await EnrichContext(context, contextType, stringModels);

            Logger.EndGroup();
        }
Esempio n. 14
0
 private int SaveStorageSets(StorageContext context, int total, Type contextType, List <PropertyInfo> storageSets)
 {
     foreach (var prop in storageSets)
     {
         var storageSetValue  = prop.GetValue(context);
         var modelType        = prop.PropertyType.GetGenericArguments()[0];
         var storageTableName = Util.GetStorageTableName(contextType, modelType);
         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);
         }
         Logger.StorageSetSaved(modelType, guids.Count);
     }
     return(total);
 }
Esempio n. 15
0
        private static IReadOnlyDictionary <string, Metadata> LoadMetadataList(StorageContext context,
                                                                               IEnumerable <PropertyInfo> storageSets, Type contextType)
        {
            var map = new Dictionary <string, Metadata>();

            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 <Guid>(),
                    ContextName = Util.GetFullyQualifiedTypeName(context.GetType()),
                    ModelName   = Util.GetFullyQualifiedTypeName(modelType)
                };
                map.Add(Util.GetFullyQualifiedTypeName(modelType), metadata);
            }

            return(map);
        }
Esempio n. 16
0
        private static string ScanModelForAssociations(object model, List <PropertyInfo> storageSets,
                                                       string serializedModel)
        {
            var result = serializedModel;

            foreach (var prop in model.GetType().GetProperties())
            {
                if (prop.GetValue(model) == null || !StorageManagerUtil.IsInContext(storageSets, prop) &&
                    !StorageManagerUtil.IsListInContext(storageSets, prop))
                {
                    continue;
                }
                if (StorageManagerUtil.IsInContext(storageSets, prop))
                {
                    result = FixOneAssociation(model, prop, result);
                }
                if (StorageManagerUtil.IsListInContext(storageSets, prop))
                {
                    result = FixManyAssociation(model, prop, result);
                }
            }

            return(result);
        }
Esempio n. 17
0
 private static bool HasListAssociation(List <PropertyInfo> storageSets, Type modelType)
 {
     return(modelType.GetProperties().Any(prop => StorageManagerUtil.IsListInContext(storageSets, prop)));
 }