private void ProcessAll()
        {
            var typesToProcess = context.ModelDef.Types
                                 .Where(t => !t.IsGenericTypeDefinition && !t.IsAutoGenericInstance);

            foreach (var type in typesToProcess)
            {
                var underlyingType = type.UnderlyingType;
                if (verbose)
                {
                    BuildLog.Info(Strings.LogProcessingX, underlyingType.GetShortName());
                }
                var           request = new MappingRequest(underlyingType.Assembly, underlyingType.Namespace);
                MappingResult result;
                if (!mappingCache.TryGetValue(request, out result))
                {
                    result = Process(underlyingType);
                    mappingCache.Add(request, result);
                }
                else
                {
                    if (verbose)
                    {
                        BuildLog.Info(Strings.LogReusingCachedMappingInformationForX, underlyingType.GetShortName());
                    }
                }
                type.MappingDatabase = result.MappingDatabase;
                type.MappingSchema   = result.MappingSchema;
            }
        }
        private static void ApplyModelFixesForMySql(DomainModelDef model)
        {
            BuildLog.Info("Applying changes to Metadata-related types for MySQL");

            // Fixing length of Assembly.Name field
            TypeDef  type = model.Types.TryGetValue(typeof(Assembly));
            FieldDef field;

            if (type != null && type.Fields.TryGetValue("Name", out field))
            {
                field.Length = 255;
            }

            // Fixing length of Extension.Name field
            type = model.Types.TryGetValue(typeof(Extension));
            if (type != null && type.Fields.TryGetValue("Name", out field))
            {
                field.Length = 255;
            }

            // Removing index on Type.Name field
            type = model.Types.TryGetValue(typeof(Type));
            if (type != null && type.Indexes.Count > 0)
            {
                var indexes = type.Indexes.Where(i => i.KeyFields.ContainsKey("Name")).ToList();
                foreach (var index in indexes)
                {
                    type.Indexes.Remove(index);
                }
            }
        }
    private void BuildNestedFields(FieldInfo source, FieldInfo target, IEnumerable<FieldInfo> fields)
    {
      var buffer = fields.ToList();

      foreach (var field in buffer) {
        var clone = field.Clone();
        if (target.SkipVersion)
          clone.SkipVersion = true;
        clone.IsSystem = false;
        clone.IsLazyLoad = field.IsLazyLoad || target.IsLazyLoad;
        if (target.IsDeclared) {
          clone.Name = context.NameBuilder.BuildNestedFieldName(target, field);
          clone.OriginalName = field.OriginalName;
          // One-field reference
          if (target.IsEntity && buffer.Count == 1) {
            clone.MappingName = target.MappingName;
            clone.DefaultValue = target.DefaultValue;
          }
          else
            clone.MappingName = context.NameBuilder.BuildMappingName(target, field);
        }
        if (target.Fields.Contains(clone.Name))
          continue;
        clone.Parent = target;
        target.ReflectedType.Fields.Add(clone);

        if (field.IsStructure || field.IsEntity) {
          BuildNestedFields(source, clone, field.Fields);
          foreach (FieldInfo clonedFields in clone.Fields)
            target.Fields.Add(clonedFields);
        }
        else {
          if (field.Column!=null)
            clone.Column = BuildInheritedColumn(clone, field.Column);
        }
        if (target.IsStructure && clone.IsEntity && !IsAuxiliaryType(clone.ReflectedType)) {
          var origin = context.Model.Associations
            .Find(context.Model.Types[field.ValueType], true)
            .FirstOrDefault(a => a.OwnerField.Equals(field));
          if (origin!=null && !clone.IsInherited) {
            AssociationBuilder.BuildAssociation(context, origin, clone);
            context.DiscardedAssociations.Add(origin);
          }
        }
        if (!clone.IsStructure && !clone.IsEntitySet && !target.ReflectedType.IsInterface && 0!=(clone.Attributes & FieldAttributes.Indexed)) {
          var typeDef = context.ModelDef.Types[target.DeclaringType.UnderlyingType];
          var attribute = new IndexAttribute(clone.Name);
          var index = context.ModelDefBuilder.DefineIndex(typeDef, attribute);
          if (typeDef.Indexes.Contains(index.Name))
            throw new DomainBuilderException(
              string.Format(Strings.ExIndexWithNameXIsAlreadyRegistered, index.Name));

          typeDef.Indexes.Add(index);
          BuildLog.Info(Strings.LogIndexX, index.Name);
        }
      }
    }
 private void ProcessAll()
 {
     using (BuildLog.InfoRegion(Strings.LogProcessingFixupActions))
         while (context.ModelInspectionResult.Actions.Count > 0)
         {
             var action = context.ModelInspectionResult.Actions.Dequeue();
             BuildLog.Info(string.Format(Strings.LogExecutingActionX, action));
             action.Run(this);
         }
 }
        public TypeDef ProcessType(Type type)
        {
            var modelDef = context.ModelDef;

            var typeDef = modelDef.Types.TryGetValue(type);

            if (typeDef != null)
            {
                return(typeDef);
            }

            using (BuildLog.InfoRegion(Strings.LogDefiningX, type.GetFullName())) {
                typeDef = DefineType(type);
                if (modelDef.Types.Contains(typeDef.Name))
                {
                    throw new DomainBuilderException(string.Format(Strings.ExTypeWithNameXIsAlreadyDefined, typeDef.Name));
                }

                HierarchyDef hierarchyDef = null;
                if (typeDef.IsEntity)
                {
                    // HierarchyRootAttribute is required for hierarchy root
                    var hra = type.GetAttribute <HierarchyRootAttribute>(AttributeSearchOptions.Default);
                    if (hra != null)
                    {
                        hierarchyDef = DefineHierarchy(typeDef, hra);
                    }
                }

                ProcessProperties(typeDef, hierarchyDef);

                if (typeDef.IsEntity || typeDef.IsInterface)
                {
                    ProcessIndexes(typeDef);
                }

                if (hierarchyDef != null)
                {
                    BuildLog.Info(Strings.LogHierarchyX, typeDef.Name);
                    modelDef.Hierarchies.Add(hierarchyDef);
                }

                modelDef.Types.Add(typeDef);

                ProcessFullTextIndexes(typeDef);

                var validators = type.GetCustomAttributes(false).OfType <IObjectValidator>();
                foreach (var validator in validators)
                {
                    typeDef.Validators.Add(validator);
                }

                return(typeDef);
            }
        }
        public void ProcessProperties(TypeDef typeDef, HierarchyDef hierarchyDef)
        {
            var properties = typeDef.UnderlyingType.GetProperties(
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (var propertyInfo in properties)
            {
                // Domain builder stage-related filter
                if (!IsFieldAvailable(propertyInfo))
                {
                    continue;
                }

                // FieldAttribute presence is required
                var reversedFieldAttributes = GetReversedFieldAttributes <FieldAttribute>(propertyInfo);
                if (reversedFieldAttributes.Count == 0)
                {
                    continue;
                }

                var field = DefineField(propertyInfo, reversedFieldAttributes);

                // Declared & inherited fields must be processed for hierarchy root
                if (hierarchyDef != null)
                {
                    typeDef.Fields.Add(field);
                    BuildLog.Info(Strings.LogFieldX, field.Name);

                    var keyAttributes = propertyInfo.GetAttribute <KeyAttribute>(AttributeSearchOptions.InheritAll);
                    if (keyAttributes != null)
                    {
                        attributeProcessor.Process(hierarchyDef, field, keyAttributes);
                    }
                }
                // Only declared properties must be processed in other cases
                else if (propertyInfo.DeclaringType == propertyInfo.ReflectedType)
                {
                    typeDef.Fields.Add(field);
                    BuildLog.Info(Strings.LogFieldX, field.Name);
                }

                // Checking whether property type is registered in model
                var propertyType = field.UnderlyingProperty.PropertyType;
                if (propertyType.IsGenericParameter)
                {
                    continue;
                }

                if (propertyType.IsSubclassOf(WellKnownOrmTypes.Persistent) && !context.ModelDef.Types.Contains(propertyType))
                {
                    types.Enqueue(propertyType);
                }
            }
        }
        private MappingResult Process(Type type)
        {
            var rule = mappingRules.First(r => RuleMatch(r, type));

            var resultDatabase = !string.IsNullOrEmpty(rule.Database) ? rule.Database : defaultDatabase;
            var resultSchema   = !string.IsNullOrEmpty(rule.Schema) ? rule.Schema : defaultSchema;

            if (verbose)
            {
                BuildLog.Info(Strings.ApplyingRuleXToY, rule, type.GetShortName());
            }

            return(new MappingResult(resultDatabase, resultSchema));
        }
    private void BuildInheritedField(TypeInfo type, FieldInfo inheritedField)
    {
      BuildLog.Info(Strings.LogBuildingInheritedFieldXY, type.Name, inheritedField.Name);
      var field = inheritedField.Clone();
      type.Fields.Add(field);
      field.ReflectedType = type;
      field.DeclaringType = inheritedField.DeclaringType;
      field.IsInherited = true;

      BuildNestedFields(inheritedField, field, inheritedField.Fields);

      if (inheritedField.Column!=null)
        field.Column = BuildInheritedColumn(field, inheritedField.Column);
    }
        public void BuildLogTest()
        {
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
            BuildLog.Debug("Test message", null);
            BuildLog.Debug("Test message with parameter {0}", new object[] { 1 });
            BuildLog.Debug(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 });
            BuildLog.Debug("Test message", new object[] { 1 });
            BuildLog.Debug("Test message {0}", null);
            BuildLog.Debug(new Exception("Some exeption"));
            BuildLog.Debug(null, new object[] { 1 });

            BuildLog.Info("Test message", null);
            BuildLog.Info("Test message with parameter {0}", new object[] { 1 });
            BuildLog.Info(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 });
            BuildLog.Info("Test message", new object[] { 1 });
            BuildLog.Info("Test message {0}", null);
            BuildLog.Info(new Exception("Some exeption"));
            BuildLog.Info(null, new object[] { 1 });

            BuildLog.Warning("Test message", null);
            BuildLog.Warning("Test message with parameter {0}", new object[] { 1 });
            BuildLog.Warning(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 });
            BuildLog.Warning("Test message", new object[] { 1 });
            BuildLog.Warning("Test message {0}", null);
            BuildLog.Warning(new Exception("Some exeption"));
            BuildLog.Warning(null, new object[] { 1 });

            BuildLog.Error("Test message", null);
            BuildLog.Error("Test message with parameter {0}", new object[] { 1 });
            BuildLog.Error(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 });
            BuildLog.Error("Test message", new object[] { 1 });
            BuildLog.Error("Test message {0}", null);
            BuildLog.Error(new Exception("Some exeption"));
            BuildLog.Error(null, new object[] { 1 });

            BuildLog.FatalError("Test message", null);
            BuildLog.FatalError("Test message with parameter {0}", new object[] { 1 });
            BuildLog.FatalError(new Exception("Some exception"), "Test message with parameter {0}", new object[] { 1 });
            BuildLog.FatalError("Test message", new object[] { 1 });
            BuildLog.FatalError("Test message {0}", null);
            BuildLog.FatalError(new Exception("Some exeption"));
            BuildLog.FatalError(null, new object[] { 1 });

            Assert.IsTrue(File.Exists(filePath));
            Assert.AreEqual(File.ReadAllLines(filePath).Count(), 35);
        }
        private void ProcessIndexes(TypeDef typeDef)
        {
            // process indexes which defined directly for type
            var ownIndexesOfType = typeDef.Fields
                                   .Where(f => f.IsIndexed)
                                   .Select(f => new IndexAttribute(f.Name))
                                   .Concat(typeDef.UnderlyingType.GetAttributes <IndexAttribute>(AttributeSearchOptions.InheritNone) ??
                                           Enumerable.Empty <IndexAttribute>());

            var ownIndexesCollection = new HashSet <IndexAttribute>();

            foreach (var attribute in ownIndexesOfType)
            {
                var index = DefineIndex(typeDef, attribute);
                ownIndexesCollection.Add(attribute);
                if (typeDef.Indexes.Contains(index.Name))
                {
                    throw new DomainBuilderException(
                              string.Format(Strings.ExIndexWithNameXIsAlreadyRegistered, index.Name));
                }

                typeDef.Indexes.Add(index);
                BuildLog.Info(Strings.LogIndexX, index.Name);
            }

            //process indexes which inherited from base classes
            //GetAttribute<T>(AttributeSearchOptions.InheritFromAllBase) extension returns all attributes of T - own indexes of type and inherited.
            var allIndexes = typeDef.UnderlyingType
                             .GetAttributes <IndexAttribute>(AttributeSearchOptions.InheritFromAllBase) ??
                             Enumerable.Empty <IndexAttribute>();

            //We need only inherited attributes. We checks all IndexAttributes in allIndexes and skip indexes
            //which own of type.
            foreach (var attribute in allIndexes.Where(index => !ownIndexesCollection.Contains(index)))
            {
                var index = DefineIndex(typeDef, attribute);
                if (typeDef.Indexes.Contains(index.Name))
                {
                    throw new DomainBuilderException(
                              string.Format(Strings.ExIndexWithNameXIsAlreadyRegistered, index.Name));
                }

                index.IsInherited = true;
                typeDef.Indexes.Add(index);
                BuildLog.Info(Strings.LogIndexX, index.Name);
            }
        }
Example #11
0
        public static void Inspect(BuildingContext context, HierarchyDef hierarchyDef)
        {
            var root = hierarchyDef.Root;

            BuildLog.Info(Strings.LogInspectingHierarchyX, root.Name);
            context.Validator.ValidateHierarchy(hierarchyDef);
            // Skip open generic hierarchies
            if (root.IsGenericTypeDefinition)
            {
                return;
            }

            // Check the presence of TypeId field
            FieldDef typeIdField;

            if (!root.Fields.TryGetValue(WellKnown.TypeIdFieldName, out typeIdField))
            {
                context.ModelInspectionResult.Actions.Enqueue(new AddTypeIdFieldAction(root));
            }
            else
            {
                context.ModelInspectionResult.Actions.Enqueue(new MarkFieldAsSystemAction(root, typeIdField));
            }

            // Should TypeId field be added to key fields?
            if (hierarchyDef.IncludeTypeId && hierarchyDef.KeyFields.Find(f => f.Name == WellKnown.TypeIdFieldName) == null)
            {
                context.ModelInspectionResult.Register(new AddTypeIdToKeyFieldsAction(hierarchyDef));
            }

            context.ModelInspectionResult.Actions.Enqueue(new ReorderFieldsAction(hierarchyDef));

            foreach (var keyField in hierarchyDef.KeyFields)
            {
                var field = root.Fields[keyField.Name];
                InspectField(context, root, field, true);
            }

            context.ModelInspectionResult.Actions.Enqueue(new AddPrimaryIndexAction(root));
        }
Example #12
0
        private FieldInfo BuildDeclaredField(TypeInfo type, FieldDef fieldDef)
        {
            BuildLog.Info(Strings.LogBuildingDeclaredFieldXY, type.Name, fieldDef.Name);

            var fieldInfo = new FieldInfo(type, fieldDef.Attributes)
            {
                UnderlyingProperty = fieldDef.UnderlyingProperty,
                Name         = fieldDef.Name,
                OriginalName = fieldDef.Name,
                MappingName  = fieldDef.MappingName,
                ValueType    = fieldDef.ValueType,
                ItemType     = fieldDef.ItemType,
                Length       = fieldDef.Length,
                Scale        = fieldDef.Scale,
                Precision    = fieldDef.Precision,
                Validators   = fieldDef.Validators,
            };

            if (fieldInfo.IsStructure && DeclaresOnValidate(fieldInfo.ValueType))
            {
                fieldInfo.Validators.Add(new StructureFieldValidator());
            }

            if (fieldInfo.IsEntitySet && DeclaresOnValidate(fieldInfo.ValueType))
            {
                fieldInfo.Validators.Add(new EntitySetFieldValidator());
            }

            type.Fields.Add(fieldInfo);

            if (fieldInfo.IsEntitySet)
            {
                AssociationBuilder.BuildAssociation(context, fieldDef, fieldInfo);
                return(fieldInfo);
            }

            if (fieldInfo.IsEntity)
            {
                var fields = context.Model.Types[fieldInfo.ValueType].Fields.Where(f => f.IsPrimaryKey);
                // Adjusting default value if any
                if (fields.Count() == 1 && fieldDef.DefaultValue != null)
                {
                    fieldInfo.DefaultValue =
                        ValueTypeBuilder.AdjustValue(fieldInfo, fields.First().ValueType, fieldDef.DefaultValue);
                }

                BuildNestedFields(null, fieldInfo, fields);

                if (!IsAuxiliaryType(type))
                {
                    AssociationBuilder.BuildAssociation(context, fieldDef, fieldInfo);
                    if (type.IsStructure)
                    {
                        fieldInfo.Associations.ForEach(a => context.DiscardedAssociations.Add(a));
                    }
                }

                // Adjusting type discriminator field for references
                if (fieldDef.IsTypeDiscriminator)
                {
                    type.Hierarchy.TypeDiscriminatorMap.Field = fieldInfo.Fields.First();
                }
            }

            if (fieldInfo.IsStructure)
            {
                BuildNestedFields(null, fieldInfo, context.Model.Types[fieldInfo.ValueType].Fields);
                var structureFullTextIndex = context.ModelDef.FullTextIndexes.TryGetValue(fieldInfo.ValueType);
                if (structureFullTextIndex != null)
                {
                    var hierarchyTypeInfo = context.Model.Types[fieldInfo.DeclaringType.UnderlyingType];
                    var structureTypeInfo = context.Model.Types[fieldInfo.ValueType];
                    var currentIndex      = context.ModelDef.FullTextIndexes.TryGetValue(hierarchyTypeInfo.UnderlyingType);
                    if (currentIndex == null)
                    {
                        currentIndex = new FullTextIndexDef(context.ModelDef.Types.TryGetValue(type.UnderlyingType));
                        context.ModelDef.FullTextIndexes.Add(currentIndex);
                    }

                    currentIndex.Fields.AddRange(structureFullTextIndex.Fields
                                                 .Select(f => new {
                        fieldInfo.DeclaringType
                        .StructureFieldMapping[new Pair <FieldInfo>(fieldInfo, structureTypeInfo.Fields[f.Name])].Name,
                        f.IsAnalyzed,
                        f.Configuration,
                        f.TypeFieldName
                    })
                                                 .Select(g => new FullTextFieldDef(g.Name, g.IsAnalyzed)
                    {
                        Configuration = g.Configuration, TypeFieldName = g.TypeFieldName
                    }));
                }
            }

            if (fieldInfo.IsPrimitive)
            {
                fieldInfo.DefaultValue         = fieldDef.DefaultValue;
                fieldInfo.DefaultSqlExpression = fieldDef.DefaultSqlExpression;
                fieldInfo.Column = BuildDeclaredColumn(fieldInfo);
                if (fieldDef.IsTypeDiscriminator)
                {
                    type.Hierarchy.TypeDiscriminatorMap.Field = fieldInfo;
                }
            }

            return(fieldInfo);
        }
Example #13
0
        public static void Inspect(BuildingContext context, TypeDef typeDef)
        {
            BuildLog.Info(Strings.LogInspectingTypeX, typeDef.Name);

            if (typeDef.IsInterface)
            {
                // Remove open generic interface
                if (typeDef.IsGenericTypeDefinition)
                {
                    context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef));
                    return;
                }

                // Base interfaces
                foreach (var @interface in context.ModelDef.Types.FindInterfaces(typeDef.UnderlyingType))
                {
                    context.DependencyGraph.AddEdge(typeDef, @interface, EdgeKind.Inheritance, EdgeWeight.High);
                }

                // Fields
                foreach (var field in typeDef.Fields)
                {
                    InspectField(context, typeDef, field, false);
                }

                return;
            }

            if (typeDef.IsStructure)
            {
                if (typeDef.UnderlyingType.IsGenericTypeDefinition)
                {
                    context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef));
                    return;
                }

                // Ancestor
                var parent = context.ModelDef.Types.FindAncestor(typeDef);
                if (parent != null)
                {
                    context.DependencyGraph.AddEdge(typeDef, parent, EdgeKind.Inheritance, EdgeWeight.High);
                }

                // Fields
                foreach (var field in typeDef.Fields)
                {
                    InspectField(context, typeDef, field, false);
                }

                return;
            }

            if (typeDef.IsEntity)
            {
                // Should we remove it or not?
                var hierarchyDef = context.ModelDef.FindHierarchy(typeDef);
                if (hierarchyDef == null)
                {
                    context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef));
                    return;
                }

                // Register closed generic types
                if (typeDef.IsGenericTypeDefinition)
                {
                    var allGenericConstraintsAreEntity = typeDef.UnderlyingType.GetGenericArguments()
                                                         .SelectMany(ga => ga.GetGenericParameterConstraints())
                                                         .All(constraintType => WellKnownOrmInterfaces.Entity.IsAssignableFrom(constraintType));
                    // Skip automatic registration for open generic types which constraints are not IEntity
                    if (!allGenericConstraintsAreEntity)
                    {
                        return;
                    }

                    if (!typeDef.IsAbstract)
                    {
                        context.ModelInspectionResult.Register(new BuildGenericTypeInstancesAction(typeDef));
                    }

                    context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef));
                    return;
                }

                // Ancestor
                var parent = context.ModelDef.Types.FindAncestor(typeDef);
                if (parent != null)
                {
                    context.DependencyGraph.AddEdge(typeDef, parent, EdgeKind.Inheritance, EdgeWeight.High);
                }

                // Interfaces
                foreach (var @interface in context.ModelDef.Types.FindInterfaces(typeDef.UnderlyingType))
                {
                    context.DependencyGraph.AddEdge(typeDef, @interface, EdgeKind.Implementation, EdgeWeight.High);
                }

                context.Validator.ValidateType(typeDef, hierarchyDef);
                // We should skip key fields inspection as they have been already inspected
                foreach (var field in typeDef.Fields.Where(f => hierarchyDef.KeyFields.All(kf => kf.Name != f.Name)))
                {
                    InspectField(context, typeDef, field, false);
                }
            }
        }
Example #14
0
 static Mod()
 {
     BuildLog.Info("Starting initialization.");
 }