Пример #1
0
 private void RegisterRenameTableHint(StoredTypeInfo oldType, StoredTypeInfo newType)
 {
     if (EnsureTableExist(oldType))
     {
         schemaHints.Add(new RenameHint(GetTablePath(oldType), GetTablePath(newType)));
     }
 }
Пример #2
0
 private void RegisterRenameFieldHint(
     StoredTypeInfo oldType, StoredTypeInfo newType, string oldColumnName, string newColumnName)
 {
     if (EnsureTableExist(oldType) && EnsureFieldExist(oldType, oldColumnName))
     {
         schemaHints.Add(
             new RenameHint(GetColumnPath(oldType, oldColumnName), GetColumnPath(newType, newColumnName)));
     }
 }
Пример #3
0
        private void GenerateClearReferenceHint(
            StoredTypeInfo removedType,
            StoredTypeInfo updatedType,
            StoredAssociationInfo association,
            bool inverse)
        {
            if (association.ReferencingField.IsEntitySet && association.ConnectorType == null)
            {
                // There is nothing to cleanup in class containing EntitySet<T> property,
                // when T is removed, and EntitySet<T> was paired to a property of T.
                return;
            }

            var identityFieldsOfRemovedType = removedType.AllFields.Where(f => f.IsPrimaryKey).ToList();
            var identityFieldsOfUpdatedType = association.ConnectorType != null
        ? association.ConnectorType.Fields
                                              .Single(field => field.Name == ((association.IsMaster ^ inverse) ? WellKnown.SlaveFieldName : WellKnown.MasterFieldName))
                                              .Fields
        : association.ReferencingField.Fields;

            var pairedIdentityFields  = JoinFieldsByOriginalName(identityFieldsOfRemovedType, identityFieldsOfUpdatedType);
            var pairedIdentityColumns = AssociateMappedFields(pairedIdentityFields);

            if (pairedIdentityColumns == null)
            {
                throw new InvalidOperationException(
                          String.Format(Strings.ExPairedIdentityColumnsForTypesXAndXNotFound, removedType, updatedType));
            }

            var sourceTablePath = GetTablePath(updatedType);
            var identities      = pairedIdentityColumns.Select(pair =>
                                                               new IdentityPair(
                                                                   GetColumnPath(updatedType, pair.Second),
                                                                   GetColumnPath(removedType, pair.First), false))
                                  .ToList();

            if (removedType.Hierarchy.InheritanceSchema != InheritanceSchema.ConcreteTable)
            {
                identities.Add(new IdentityPair(
                                   GetColumnPath(removedType, GetTypeIdMappingName(removedType)),
                                   removedType.TypeId.ToString(), true));
            }
            var updatedColumns = pairedIdentityColumns.Select(pair =>
                                                              new Pair <string, object>(GetColumnPath(updatedType, pair.Second), null))
                                 .ToList();

            if (association.ConnectorType == null)
            {
                schemaHints.Add(new UpdateDataHint(sourceTablePath, identities, updatedColumns));
            }
            else
            {
                schemaHints.Add(new DeleteDataHint(sourceTablePath, identities));
            }
        }
Пример #4
0
        private string GetColumnPath(StoredTypeInfo type, string columnName)
        {
            var nodeName = GetTableName(type);
            // Due to current implementation of domain model FieldInfo.MappingName is not correct,
            // it has naming rules unapplied, corresponding ColumnInfo.Name however is correct.
            // StoredFieldInfo.MappingName is taken directly from FieldInfo.MappingName and thus is incorrect too.
            // We need to apply naming rules here to make it work.
            var actualColumnName = nameBuilder.ApplyNamingRules(columnName);

            return(string.Format("Tables/{0}/Columns/{1}", nodeName, actualColumnName));
        }
Пример #5
0
 private void GenerateClearReferenceHints(
     StoredTypeInfo removedType,
     StoredTypeInfo[] updatedTypes,
     StoredAssociationInfo association,
     bool inverse)
 {
     foreach (var updatedType in updatedTypes)
     {
         GenerateClearReferenceHint(removedType, updatedType, association, inverse);
     }
 }
Пример #6
0
 private void MapType(StoredTypeInfo oldType, StoredTypeInfo newType)
 {
     if (typeMapping.TryGetValue(oldType, out var existingNewType))
     {
         throw new InvalidOperationException(string.Format(
                                                 Strings.ExUnableToAssociateTypeXWithTypeYTypeXIsAlreadyMappedToTypeZ,
                                                 oldType, newType, existingNewType));
     }
     typeMapping[oldType]        = newType;
     reverseTypeMapping[newType] = oldType;
 }
Пример #7
0
        private bool EnsureTableExist(StoredTypeInfo type)
        {
            var nodeName = GetTableName(type);

            if (extractedStorageModel.Tables.Contains(nodeName))
            {
                return(true);
            }

            UpgradeLog.Warning(Strings.ExTableXIsNotFound, nodeName);
            return(false);
        }
Пример #8
0
        private static StoredTypeInfo[] GetAffectedMappedTypesAsArray(StoredTypeInfo type, bool includeInheritors)
        {
            var count  = 1;
            var result = EnumerableUtils.One(type);

            if (includeInheritors)
            {
                result = result.Concat(type.AllDescendants);
                count += type.AllDescendants.Length;
            }
            return(type.Hierarchy.InheritanceSchema == InheritanceSchema.ConcreteTable
        ? result.Where(t => !t.IsAbstract).ToArray()
        : result.ToArray(count));
        }
Пример #9
0
        private static IEnumerable <StoredTypeInfo> GetAffectedMappedTypes(StoredTypeInfo type, bool includeInheritors)
        {
            var result = EnumerableUtils.One(type);

            if (includeInheritors)
            {
                result = result.Concat(type.AllDescendants);
            }
            if (type.Hierarchy.InheritanceSchema == InheritanceSchema.ConcreteTable)
            {
                result = result.Where(t => !t.IsAbstract);
            }
            return(result);
        }
Пример #10
0
        private bool EnsureFieldExist(StoredTypeInfo type, string fieldName)
        {
            if (!EnsureTableExist(type))
            {
                return(false);
            }
            var nodeName        = GetTableName(type);
            var actualFieldName = nameBuilder.ApplyNamingRules(fieldName);

            if (extractedStorageModel.Tables[nodeName].Columns.Contains(actualFieldName))
            {
                return(true);
            }
            UpgradeLog.Warning(Strings.ExColumnXIsNotFoundInTableY, actualFieldName, nodeName);
            return(false);
        }
Пример #11
0
        private List <string> GetAffectedColumns(StoredTypeInfo type, StoredFieldInfo field)
        {
            var affectedColumns = new List <string>();

            if (type.IsStructure)
            {
                var structureFields = extractedModel.Types
                                      .Where(t => t.IsEntity)
                                      .SelectMany(t => extractedModelFields[t].Where(f => f.IsStructure && f.ValueType == type.UnderlyingType));

                foreach (var structureField in structureFields)
                {
                    var nestedField = structureField.Fields.FirstOrDefault(f => f.OriginalName == field.Name);
                    if (nestedField != null)
                    {
                        affectedColumns.AddRange(GetAffectedColumns(structureField.DeclaringType, nestedField));
                    }
                }

                return(affectedColumns);
            }

            foreach (var primitiveField in field.PrimitiveFields)
            {
                var inheritanceSchema = type.Hierarchy.InheritanceSchema;
                switch (inheritanceSchema)
                {
                case InheritanceSchema.ClassTable:
                    affectedColumns.Add(GetColumnPath(primitiveField.DeclaringType, primitiveField.MappingName));
                    break;

                case InheritanceSchema.SingleTable:
                    affectedColumns.Add(GetColumnPath(type.Hierarchy.Root, primitiveField.MappingName));
                    break;

                case InheritanceSchema.ConcreteTable:
                    var columns = GetAffectedMappedTypes(type, true)
                                  .Select(t => GetColumnPath(t, primitiveField.MappingName));
                    affectedColumns.AddRange(columns);
                    break;

                default:
                    throw Exceptions.InternalError(String.Format(Strings.ExInheritanceSchemaIsInvalid, inheritanceSchema), UpgradeLog.Instance);
                }
            }
            return(affectedColumns);
        }
Пример #12
0
 private void GenerateRenameFieldHint(StoredFieldInfo oldField, StoredFieldInfo newField,
                                      StoredTypeInfo newType, bool includeInheritors)
 {
     if (oldField.MappingName == newField.MappingName)
     {
         return;
     }
     foreach (var newTargetType in GetAffectedMappedTypes(newType, includeInheritors))
     {
         StoredTypeInfo oldTargetType;
         if (!reverseTypeMapping.TryGetValue(newTargetType, out oldTargetType))
         {
             continue;
         }
         RegisterRenameFieldHint(oldTargetType, newTargetType, oldField.MappingName, newField.MappingName);
     }
 }
Пример #13
0
        private void GenerateCleanupByPrimaryKeyHints(StoredTypeInfo removedType, bool isMovedToAnotherHierarchy)
        {
            var hierarchy = removedType.Hierarchy;

            switch (hierarchy.InheritanceSchema)
            {
            case InheritanceSchema.ClassTable:
                IEnumerable <StoredTypeInfo> typesToProcess;
                typesToProcess = !isMovedToAnotherHierarchy
            ? EnumerableUtils.One(removedType).Concat(removedType.AllAncestors)
            : removedType.AllAncestors;

                foreach (var type in typesToProcess)
                {
                    var identities1 = new[] { new IdentityPair(
                                                  GetColumnPath(type, GetTypeIdMappingName(type)),
                                                  removedType.TypeId.ToString(),
                                                  true) };
                    schemaHints.Add(
                        new DeleteDataHint(GetTablePath(type), identities1, isMovedToAnotherHierarchy));
                }
                break;

            case InheritanceSchema.SingleTable:
                var rootType    = hierarchy.Root;
                var identities2 = new[] { new IdentityPair(
                                              GetColumnPath(rootType, GetTypeIdMappingName(rootType)),
                                              removedType.TypeId.ToString(),
                                              true) };
                schemaHints.Add(
                    new DeleteDataHint(GetTablePath(rootType), identities2, isMovedToAnotherHierarchy));
                break;

            case InheritanceSchema.ConcreteTable:
                // ConcreteTable schema doesn't include TypeId
                schemaHints.Add(
                    new DeleteDataHint(GetTablePath(removedType), Array.Empty <IdentityPair>(), isMovedToAnotherHierarchy));
                break;

            default:
                throw Exceptions.InternalError(string.Format(Strings.ExInheritanceSchemaIsInvalid, hierarchy.InheritanceSchema), UpgradeLog.Instance);
            }
        }
Пример #14
0
        private void GenerateCleanupByPrimaryKeyHints(StoredTypeInfo removedType, bool isMovedToAnotherHierarchy)
        {
            var typesToProcess = new List <StoredTypeInfo>();
            var hierarchy      = removedType.Hierarchy;

            switch (hierarchy.InheritanceSchema)
            {
            case InheritanceSchema.ClassTable:
                if (!isMovedToAnotherHierarchy)
                {
                    typesToProcess.Add(removedType);
                }
                typesToProcess.AddRange(removedType.AllAncestors);
                break;

            case InheritanceSchema.SingleTable:
                typesToProcess.Add(hierarchy.Root);
                break;

            case InheritanceSchema.ConcreteTable:
                typesToProcess.Add(removedType);
                break;

            default:
                throw Exceptions.InternalError(String.Format(Strings.ExInheritanceSchemaIsInvalid, hierarchy.InheritanceSchema), UpgradeLog.Instance);
            }
            foreach (var type in typesToProcess)
            {
                var sourceTablePath = GetTablePath(type);
                var identities      = new List <IdentityPair>();
                // ConcreteTable schema doesn't include TypeId
                if (hierarchy.InheritanceSchema != InheritanceSchema.ConcreteTable)
                {
                    identities.Add(new IdentityPair(
                                       GetColumnPath(type, GetTypeIdMappingName(type)),
                                       removedType.TypeId.ToString(),
                                       true));
                }
                schemaHints.Add(
                    new DeleteDataHint(sourceTablePath, identities, isMovedToAnotherHierarchy));
            }
        }
Пример #15
0
        private bool IsMovedToAnotherHierarchy(StoredTypeInfo oldType)
        {
            var newType = typeMapping.GetValueOrDefault(oldType);

            if (newType == null)
            {
                return(false); // Type is removed
            }
            var oldRoot = oldType.Hierarchy.Root;

            if (oldRoot == null)
            {
                return(false); // Just to be sure
            }
            var newRoot = newType.Hierarchy.Root;

            if (newRoot == null)
            {
                return(false); // Just to be sure
            }
            return(newRoot != typeMapping.GetValueOrDefault(oldRoot));
        }
Пример #16
0
        private string GetTablePath(StoredTypeInfo type)
        {
            var nodeName = GetTableName(type);

            return(string.Format("Tables/{0}", nodeName));
        }
Пример #17
0
 private string GetTableName(StoredTypeInfo type)
 {
     return(resolver.GetNodeName(
                type.MappingDatabase, type.MappingSchema, type.MappingName));
 }
Пример #18
0
        private static string GetTablePath(this MappingResolver resolver, StoredTypeInfo type)
        {
            var nodeName = resolver.GetTableName(type);

            return(string.Format("Tables/{0}", nodeName));
        }
Пример #19
0
 private string GetTablePath(StoredTypeInfo type) => $"Tables/{GetTableName(type)}";
Пример #20
0
 private static string GetTypeIdMappingName(StoredTypeInfo type)
 {
     return(type.AllFields
            .Single(field => field.Name.Equals(WellKnown.TypeIdFieldName, StringComparison.Ordinal))
            .MappingName);
 }
        private void BuildFieldMapping(IEnumerable <RenameFieldHint> renames, IEnumerable <ChangeFieldTypeHint> typeChanges,
                                       StoredTypeInfo oldType, StoredTypeInfo newType)
        {
            var newFields = newType.Fields.ToDictionary(field => field.Name);

            foreach (var oldField in oldType.Fields)
            {
                var renameHint   = renames.FirstOrDefault(hint => hint.OldFieldName == oldField.Name && hint.TargetType.GetFullName() == newType.UnderlyingType);
                var newFieldName = renameHint != null
          ? renameHint.NewFieldName
          : oldField.Name;

                var newField = newFields.GetValueOrDefault(newFieldName);
                if (newField == null)
                {
                    continue;
                }

                if (oldField.IsStructure)
                {
                    // If it is structure, we map it immediately
                    MapField(oldField, newField);
                    continue;
                }

                var typeChangeHint = typeChanges
                                     .FirstOrDefault(hint => hint.Type.GetFullName() == newType.UnderlyingType && hint.FieldName == newField.Name);
                if (typeChangeHint == null)
                {
                    // Check & skip field if type is changed
                    var newValueTypeName = newField.IsEntitySet
            ? newField.ItemType
            : newField.ValueType;
                    var oldValueTypeName = oldField.IsEntitySet
            ? oldField.ItemType
            : oldField.ValueType;
                    var newValueType = currentTypes.GetValueOrDefault(newValueTypeName);
                    var oldValueType = extractedTypes.GetValueOrDefault(oldValueTypeName);
                    if (newValueType != null && oldValueType != null)
                    {
                        // We deal with reference field
                        var mappedOldValueType = typeMapping.GetValueOrDefault(oldValueType);
                        if (mappedOldValueType == null)
                        {
                            // Mapped to nothing = removed
                            continue;
                        }
                        if (mappedOldValueType != newValueType && !newValueType.AllDescendants.Contains(mappedOldValueType))
                        {
                            // This isn't a Dog -> Animal type mapping
                            continue;
                        }
                    }
                    else
                    // We deal with regular field
                    if (oldValueTypeName != newValueTypeName)
                    {
                        continue;
                    }
                }
                MapField(oldField, newField);
            }
        }
Пример #22
0
 public static string GetTableName(this MappingResolver resolver, StoredTypeInfo type)
 {
     return(resolver.GetNodeName(
                type.MappingDatabase, type.MappingSchema, type.MappingName));
 }
Пример #23
0
 private bool IsRemoved(StoredTypeInfo type)
 {
     return(!typeMapping.ContainsKey(type));
 }
Пример #24
0
        private static string GetTypeIdMappingName(StoredTypeInfo type)
        {
            var typeIdField = type.AllFields.Single(field => field.Name == WellKnown.TypeIdFieldName);

            return(typeIdField.MappingName);
        }
Пример #25
0
        private void GenerateCleanupByForeignKeyHints(StoredTypeInfo removedType)
        {
            var removedTypeAndAncestors = removedType.AllAncestors.ToHashSet();

            removedTypeAndAncestors.Add(removedType);
            var affectedAssociations = (
                from association in extractedModel.Associations
                let requiresInverseCleanup =
                    association.IsMaster &&
                    association.ConnectorType != null &&
                    removedTypeAndAncestors.Contains(association.ReferencingField.DeclaringType)
                    where
                    // Regular association X.Y, Y must be cleaned up
                    removedTypeAndAncestors.Contains(association.ReferencedType) ||
                    // X.EntitySet<Y>, where X is in removedTypeAndAncestors,
                    // connectorType.X must be cleaned up as well
                    requiresInverseCleanup
                    select new { association, requiresInverseCleanup }
                ).ToList();

            foreach (var pair in affectedAssociations)
            {
                var  association            = pair.association;
                bool requiresInverseCleanup = pair.requiresInverseCleanup;
                if (association.ConnectorType == null)
                {
                    // This is regular reference
                    var field         = association.ReferencingField;
                    var declaringType = field.DeclaringType;
                    if (declaringType.IsInterface)
                    {
                        var candidates = (extractedModel.Types.Where(
                                              t => !t.IsInterface && t.Fields.Any(
                                                  f => f.IsInterfaceImplementation && f.Name == field.Name && f.ValueType == field.ValueType)))
                                         .ToList();
                        foreach (var candidate in candidates)
                        {
                            var inheritanceSchema = candidate.Hierarchy.InheritanceSchema;
                            GenerateClearReferenceHints(
                                removedType,
                                GetAffectedMappedTypes(candidate, inheritanceSchema == InheritanceSchema.ConcreteTable).ToArray(),
                                association,
                                requiresInverseCleanup);
                        }
                    }
                    else
                    {
                        var inheritanceSchema = declaringType.Hierarchy.InheritanceSchema;
                        GenerateClearReferenceHints(
                            removedType,
                            GetAffectedMappedTypes(declaringType, inheritanceSchema == InheritanceSchema.ConcreteTable).ToArray(),
                            association,
                            requiresInverseCleanup);
                    }
                }
                else
                {
                    // This is EntitySet
                    GenerateClearReferenceHints(
                        removedType,
                        new [] { association.ConnectorType },
                        association,
                        requiresInverseCleanup);
                }
            }
        }